ByteBuddy - Getting error while passing array in annotation's value - bytecode

Consider an example of building a new class instance and adding below annotation.
.annotateMethod(
AnnotationDescription.Builder.ofType(OneToMany.class)
.define("cascade", new CascadeType[]{CascadeType.PERSIST, CascadeType.MERGE})
.define("fetch", FetchType.LAZY)
.define("targetEntity", EntityB.class)
.build())
Everything works fine except assigning the "cascade" value. Getting compile-time error because .define method is not expecting an array of enums.
How can I pass an array as an Annotaion's value assignment?
For example, I want to assign an array of enum as below:
#ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})

As Holger points out, use defineEnumerationArray as documented in the javadoc.
The overloads are limited to avoid a conflict with defining a single enum value property compared to defining an enumeration array with a single value.

Related

Initialize non existing keys to empty array list

I have a class :
class Con {
private List<Ind> inds;
}
I am using Gson in the usual way to convert a JSON string to this class object. so in case, the JSON doesn't have the key inds present this variable inds is assigned a null value. Is there a way to assign inds an empty ArrayList instead?
My Thoughts:
One straightforward way could be once the Gson object is built. Go over all the null objects and assign them to the new ArrayList<>(). Is there a better approach?
public List<Ind> getInds() {
return inds;
}
Currently I am using the above getter in a code like : con.getInds().stream() which is causing NullPointerException.
I am not sure what would be a good way to resolve this. Instead of List Should I return an Optional or Should I modify this getter like
public List<Ind> getInds() {
inds==null?new ArrayList<>():inds;
}
The above will also resolve the NullPointerException. Not sure if there are pros and cons to using this approach. Although now there is no way to identify if the Json has a key with name inds or not. For the current code that I am writing this may not be required. But there is a meaning loss here certainly.
One solution to this would be to assign default values to the fields, for example:
class Con {
private List<Ind> inds = new ArrayList<>();
}
Gson will keep this default value; only if the field is present in the JSON data it will reassign the field value.
There are however a few things to keep in mind:
Your class needs a no-args constructor (implicit or explicit); otherwise Gson might create instances without invoking the initializer blocks of the class, and therefore the field will be null
If the field is present in JSON but has a JSON null value, then Gson will still set that as value
You cannot tell afterwards whether the field was present in JSON but had an empty JSON array as value, or whether it was missing

Exclude 0 from JSON response in Jackson Spring boot

I have a POJO like this.
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonIgnoreProperties(ignoreUnknown = true)
public class Test {
private int a;
private String b;
}
I want to exclude the property 'a' if it has 0 value. String b is excluded with
#JsonInclude(JsonInclude.Include.NON_NULL)
Only way I could thing of is convert the int data type to Integer Object and set the value to NULL in the setter explicitly if it is 0.
Any other suggestions or correct solution will be appreciated
Option 1:
Do what you said: Change int to Integer and use #JsonInclude(Include.NON_NULL). Because primitive types have default values and their values cannot be compared to null you have to wrap the int to Integer. See Primitive Data Types. imho this is the cleaner way.
Option 2:
Use the way described in this answer and use #JsonInclude(Include.NON_DEFAULT) instead (see Jackson-annotations API), so that default values (and so also null values for objects) will be ignored.
Note:
If you only want to exclude the specific field (in your case the int/Integer - a - field) when it has a null-/default value and the other fields (in your case the String - b - field) should be included when they have null-/default values, put the annotation on field level.

how to detect missing primitive in request instead of defaulting the actual value to 0 in springboot?

I have a rest controller that receives a Json request which is wrapped in a DTO. In that DTO I have this field.
#NotNull(message = "value is mandatory.")
private double value;
The problem is that when I send a request missing this value, I dont get a validation error because maybe the value defaults to 0.
How can I make sure that I notify the caller if this value is actually missing in the payload and not default to 0 automatically in spring?
Used #M.Deinum's suggestion and it worked okay. Involves avoiding using primitives
#NotNull(message = "value is mandatory.")
private Double value;
I have a suggestion you can add one more annotation which helps you to avoid using zero like this
#Min(1)
#NotNull(message = "value is mandatory.")
private double value;
Now it will take min value 1 so maybe it will work

Annotation with default values

In my code, I have several uses of the same annotation which has three property values, one of which always has the same value.
#ApiModelProperty(value = "some value",
allowableValues = "available,pending,sold", dataType="myclass.Payload")
dataType="myclass.Payload" is always the same value.
Is there anyway I can get a bit of code reuse here?

Spring MVC - Throws exception when the int value of ModelAttribute is null

I'm building an web application using Spring 3.0 MVC.
I have a method which has prototype below.
#RequestMapping(value = "/blahblah/blah.do", method=RequestMethod.GET)
public void searchData(#RequestParam(value="uniqOid", required=false) String uniqOid, #ModelAttribute("MasterVo") MasterVo searchVo,
ModelMap model, HttpServletResponse response, HttpServletRequest request)
The problem is that, the view (jsp) contains inputs that matches to searchVo(ModelAttribute).
When the int or long value of searchVo didn't come from the jsp, the server throws 404 page not found exception.
If the type of value is "String", it has no problem.
In my opinion, it is the problem of type casting.
How could I solve this problem, and which part of the server code that I have to check?
Thanks in advance.
I will go ahead and assume a few things about your problem.
It is not a type-cast problem. Spring has default converters that can easily convert from a String to some primitive type.
Now what you are facing is I think a null assigment to primitive type problem. Suppose the name of the property that's causing the problem is named primitiveProperty. Now, the request-paramters could include a parameter named primitiveProperty with an empty-String value, or some value that cannot be converted to a number. If the type of the primitiveProperty is String, it can assign the value of that parameter to it without any problem.
If the type of the primitiveProperty is int, long or some other primitive type that cannot have a null value, a problem occurs. When Spring converts the empty-string or a non-numeric string valued request-param named primitiveProperty, it cannot do so since that string can't be converted to a valid int or long value. So it is converted to null. Now, when Spring tries to assign that null value to a property that cannot have a null value (any primitve type), you get an Exception. If you are getting an empty-string as your request-param, you can replace the troublesome property in your domain object with its equivalent wrapper class (int with Integer, long with Long and so on). If you are getting a non-numeric value from your view, well, make sure that you don't get a non-numeric value.
You need to check the setter of the fields that are giving the typecast problem, in your case MasterVo .
The Spring will call the setter of the property to bind the value, where i presume you will see the error coming.
Just add a debug point to this setter and you will see the problem.

Resources