Grails multiple databinding domain classes - data-binding

Class Carro {
String name
String marca
String matricula
}
Class CarroMovel{
String pro1
String prop2
String prop3
Carro carro
static hasMany = [ carros: Carro]
}
def save2 = {
def carroInstance = new Carro()
def carroMovelInstance = new CarroMovel()
carroInstance.name = params.name
carroInstance.marca = params.marca
carroInstance.matricula = params.matricula
carroMovelInstance.prop1 = params.carroMovel.prop1
carroMovelInstance.prop2 = params.carroMovel.prop2
carroMovelInstance.prop3 = params.carroMovel.prop3
carroInstance.save()
carroMovelInstance.carro = carroInstance
carroMovelInstance.save()
}
The CarroInstance is saving, but the carroMovelInstance isn't. I cannot figure it out. Any help would be apreciated.

You probably have a validation error. Try calling validate() on it and inspecting the errors. Alternatively, try saving it with carroMovelInstance.save(failOnError: true) and you'll get an exception if it doesn't validate.

Related

Problem representing form-data and returning array of byte in Springdoc

I have the following piece of code,
#PostMapping(value = "/create/{userId}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<Object> saveFile(
#Parameter(description = "ID of the user") #PathVariable(value = "userId") final String userId,
#Parameter(description = "Avatar of the user", content = #Content(mediaType = MediaType.APPLICATION_OCTET_STREAM_VALUE)) #RequestParam(value = "avatar", required = true) final MultipartFile file
) {
...
}
#GetMapping(value = "/get", produces = MediaType.IMAGE_PNG_VALUE)
#ApiResponse(responseCode = "200", description = "OK", content = {#Content(array = #ArraySchema(schema = #Schema(implementation = Byte.class)))})
public ResponseEntity<byte[]> getFile() {
...
}
And below are the expected and the actual result.
How do I achieve the expected result? The expected results are from Springfox.
For file format, the not type byte on the spec. You should send type: string, format: binary.
https://swagger.io/docs/specification/describing-request-body/file-upload/
So, your requestBody for the post methods is correct.
To describe the return of type array of byte on your POST method, you can add the following description:
#ApiResponse(content = #Content(schema = #Schema(type = "string", format = "binary")))
I was faced the same problem last week. My solution was to replace the return type byte-Array by String via SpringDocUtils:
import org.springframework.context.annotation.Configuration;
import org.springdoc.core.SpringDocUtils;
#Configuration
public class OpenApiConfiguration {
static {
SpringDocUtils.getConfig()
.replaceWithClass(byte[].class, String.class);
}
}
For me the advantage of this approach is that every byte[] will be replaced by a String representation, so no corresponding explicit annotations via #ApiResponse are required. But I think this depends on the use case.

How to fetch local attribute value through QuerySpec in Windchill

I created a local string type attribute on a type in Windchill. I'm trying to fetch the value of that attribute using QuerySpec but it's throwing the following exception:
2019-04-16 20:53:05,092 INFO [ajp-nio-127.0.0.1-8011-exec-5]
wt.system.err - wt.query.QueryException: Attribute
"ptc_str_89typeInfoLCSProduct" is not a member of class "class
com.lcs.wc.product.LCSSKU" 2019-04-16 20:53:05,092 INFO
[ajp-nio-127.0.0.1-8011-exec-5] wt.system.err - Nested exception is:
Attribute "ptc_str_89typeInfoLCSProduct" is not a member of class
"class com.lcs.wc.produ
Following is my code:
String colorwayId = product.getFlexType().getAttribute("colorwayID")
.getColumnName();
QuerySpec qs = new QuerySpec();
int classIndex = qs.appendClassList(typeDefRef.getKey().getClass(), false);
ClassAttribute ca = new ClassAttribute(
typeDefRef.getKey().getClass(), colorwayId);
qs.appendSelect(ca, new int[] { classIndex }, false);
QueryResult qr = PersistenceHelper.manager.find(qs);
Normally ClassAttribute gets attribute name instead of column name (database column).
Your ptc_str_89typeInfoLCSProduct column is in fact typeInfoLCSProduct.ptc_str_89 like State is state.state.
To get this information, you need to use PersistableAdapter like this:
public String getAttributeColumnName(String softType, String logicalAttributeName) throws WTException {
PersistableAdapter persistableAdapter = new PersistableAdapter(softType, Locale.getDefault(), Operation.DISPLAY);
persistableAdapter.load(logicalAttributeName);
AttributeTypeSummary attributeDescriptor = persistableAdapter.getAttributeDescriptor(logicalAttributeName);
return null != attributeDescriptor ? (String) attributeDescriptor.get(AttributeTypeSummary.DESCRIPTION) : null;
}
And then use this method:
String colorwayId = getAttributeColumnName("your_softtype", "attribute_name_from_type_manager");

How can I use template-methods in groovy-servlet with out compile?

I have a groovy-servlet named query1_action.groovy as:
String sql = "...";
String sql_count = "...";
try {
def ctx = new javax.naming.InitialContext().lookup("java:/comp/env");
def datasource = ctx.lookup("jdbc/tlink");
def executer = Sql.newInstance(datasource);
def rows = executer.rows(sql);
def gson = new com.google.gson.GsonBuilder().setDateFormat("yyyy-MM-dd").create();
def result = gson.toJson(rows);
def rows_count = executer.firstRow(sql_count).num;
int page_count = (rows_count+page_size-1)/page_size;
out << """{"rs": "1", "rows": ${result}, "rows_count": ${rows_count}, "page": {"page_size": ${page_size}, "page_count": ${page_count}, "pn": ${p.pn}}}""";
} catch(Exception e) {
context.log("query1_action.groovy === ${e}");
out << '{"rs": "0"}';
}
I have query1_action.groovy, query2_action.groovy, and so on, all the try-catch parts are the same.
And I want to make a template-methods by this part.
I do not know how to extends some base class in this case, when I extends class, groovy servlet can not run.
How to make that please?

LINQ dynamic property in select

// Hi everyone
i do this call in Action :
[HttpGet]
public virtual ActionResult JsonGetProvinces(int countryId)
{
//WebSiteContext WbContext = new WebSiteContext();
//UnitOfWork UnitofWork = new UnitOfWork(WbContext);
var provinces =
(
from province in unitofWork.ProvinceRepository.All
where province.CountryId == countryId
select new
{
Id = province.Id,
Name = province.GetType().GetProperty("Name_" + CultureManager.GetCurrentCultureShortName()).GetValue(province)
}
).ToList();
return Json(provinces, JsonRequestBehavior.AllowGet);
}
something is wrong with my query :
var provinces =
(
from province in unitofWork.ProvinceRepository.All
where province.CountryId == countryId
select new
{
Id = province.Id,
Name = province.GetType().GetProperty("Name_" + CultureManager.GetCurrentCultureShortName()).GetValue(province)
}
).ToList();
Particulary,
Name = province.GetType().GetProperty("Name_" + CultureManager.GetCurrentCultureShortName()).GetValue(province)
In BDD, there is Name_fr, Name_en columns
and i'm trying to take one dynamically... Is it possible ?
Of course, i can take both and choose dynamically the column in View but i would to know how do...
Thank you for your help
The short answer is you need to change your code a bit and using expression tree inside. Look at this question
EF can not translate function calls to SQL. Using expression trees can be comlicated see this question
Here is a sample with expression trees. The GetQuery2 is the same as GetQuery but with expression tree and a propertyname parameter.
public static IQueryable<Foo> GetQuery(BlogContext context)
{
var query = from x in context.BlogEntries
select new Foo
{
NameX = x.Name
};
return query;
}
public static IQueryable<Foo> GetQuery2(BlogContext context, string propertyName)
{
ConstructorInfo ci = typeof(Foo).GetConstructor(new Type[0]);
MethodInfo miFooGetName = typeof(Foo).GetMethod("set_NameX");
MethodInfo miBlogEntry = typeof(BlogEntry).GetMethod("get_" + propertyName);
ParameterExpression param = Expression.Parameter(typeof(BlogEntry), "x");
IQueryable<Foo> result = Queryable.Select<BlogEntry, Foo>(
context.BlogEntries,
Expression.Lambda<Func<BlogEntry, Foo>>(
Expression.MemberInit(
Expression.New(ci, new Expression[0]),
new MemberBinding[]{
Expression.Bind(miFooGetName,
Expression.Property(param,
miBlogEntry))}
),
param
)
);
return result;
}
It is easier the fetch all all language strings and write an additional Property Name that does the magic.

Grails databinding doubt

Class Carro {
String name
String marca
String matricula
}
Class CarroMovel{
String pro1
String prop2
String prop3
Carro carro
static hasMany = [ carros: Carro]
}
def save2 = {
def carroInstance = new Carro()
def carroMovelInstance = new CarroMovel()
carroInstance.name = params.name
carroInstance.marca = params.marca
carroInstance.matricula = params.matricula
carroMovelInstance.prop1 = params.carroMovel.prop1
carroMovelInstance.prop2 = params.carroMovel.prop2
carroMovelInstance.prop3 = params.carroMovel.prop3
carroInstance.save()
carroMovelInstance.carro = carroInstance
carroMovelInstance.save()
}
The CarroInstance is saving, but the carroMovelInstance isn't. I cannot figure it out. Any help would be apreciated.
Grooveek is correct in that you haven't ever invoked carroMovelInstance.save().
However, it might be simpler for you to simply take advantage of Grails' databinding, instead of unnecessarily creating the associations and manually binding the parameters.
// Update your Carro domain.
def Carro {
String name
String marca
String matricula
// will cause persistence operations to cascade from CarroMovel to Carro
static belongsTo = CarroMovel
}
// Update your save2 action.
// By passing 'params' to the CarroMovel constructor, Grails will bind request
// parameters to domain properties of the same name; it even works with associations!
def save2 = {
def carroMovelInstance = new CarroMovel(params)
if(carroMovelInstance.validate) {
carroMovelInstance.save()
}
}
Read up on Grails Data Binding, particularly the parts about associations. Additionally, read "Understanding Cascading Updates and Deletes" to understand how a call to save() on a parent domain object will (or will not) cascade to an associated domain object.
you never ask for the carroMovelInstance to save... The carro instance has nor reference to carroMovel instance so there is no cascading of saving

Resources