I've a very extensive java POJO [81 fields] which i'm trying to deserialize from a json. The json has many missing properties and I would like jackson set them to null or default on per case basis.
It seems to be working well for non primite properties, but the whole deserialization fails when a boolean is missing in the json...
I wont be copy pasting the whole pojo here simple to avoid text overflow...
but it looks like
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Model implements Persistable<Long>, AddressableEntity, Cloneable {
...//80 different fields here
@Column(name = "exported", nullable = true, unique = false, insertable = true, updatable = true)
@JsonProperty(value = "exported", defaultValue = "false")
private boolean exported = false;
}
then there is the main class [which is also super big and i wont be copying everything in here]
@Autowired
public void setB(@NonNull Module m) throws JsonProcessingException {
ObjectMapper om = new ObjectMapper();
om.registerModule(m);
om.enable(JsonParser.Feature.INCLUDE_SOURCE_IN_LOCATION);
om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
om.configure(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY, false);
om.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false);
// JSON string with missing boolean property
String json = "{....all properties except 'exported'....}";
System.out.println(om.readValue(json , Model.class));
}
I've extensively debbuged and pinpointed the problem to the missing boolean property... Also, i've made two tests
String json = "{....all properties except 'exported'....}"; //adding exported:true or exported:false makes the code work
@Column(name = "exported", nullable = true, unique = false, insertable = true, updatable = true)
@JsonProperty(value = "exported", defaultValue = "false")
private Boolean exported = false; //changin to object Boolean also makes it work
does anyone know what can be causing jackson to have this behavior?
It might look simple to just change it to Boolean, but i've many other primitive types in the pojo, and if the json request comes without them it means the code wont work as well
===========================
exception
Caused by: com.fasterxml.jackson.databind.exc.ValueInstantiationException: Cannot construct instance of `com.bla.blabla.domain.entities.Model`, problem: `java.lang.IllegalArgumentException`
at [ line: 1, column: 4261]
at com.fasterxml.jackson.databind.exc.ValueInstantiationException.from(ValueInstantiationException.java:47) ~[jackson-databind-2.16.1.jar:2.16.1]
at com.fasterxml.jackson.databind.DeserializationContext.instantiationException(DeserializationContext.java:2014) ~[jackson-databind-2.16.1.jar:2.16.1]
at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.wrapAsJsonMappingException(StdValueInstantiator.java:598) ~[jackson-databind-2.16.1.jar:2.16.1]
at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.rewrapCtorProblem(StdValueInstantiator.java:621) ~[jackson-databind-2.16.1.jar:2.16.1]
at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromObjectWith(StdValueInstantiator.java:293) ~[jackson-databind-2.16.1.jar:2.16.1]
at com.fasterxml.jackson.databind.deser.ValueInstantiator.createFromObjectWith(ValueInstantiator.java:301) ~[jackson-databind-2.16.1.jar:2.16.1]
at com.fasterxml.jackson.databind.deser.impl.PropertyBasedCreator.build(PropertyBasedCreator.java:202) ~[jackson-databind-2.16.1.jar:2.16.1]
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:526) ~[jackson-databind-2.16.1.jar:2.16.1]
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1493) ~[jackson-databind-2.16.1.jar:2.16.1]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:348) ~[jackson-databind-2.16.1.jar:2.16.1]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:185) ~[jackson-databind-2.16.1.jar:2.16.1]
at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:342) ~[jackson-databind-2.16.1.jar:2.16.1]
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4899) ~[jackson-databind-2.16.1.jar:2.16.1]
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3846) ~[jackson-databind-2.16.1.jar:2.16.1]
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3814) ~[jackson-databind-2.16.1.jar:2.16.1]
at br.com.fisgar.crawler_iptu_campinas.Application.setB(Application.java:63) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:724) ~[spring-beans-5.3.22.jar:5.3.22]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119) ~[spring-beans-5.3.22.jar:5.3.22]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399) ~[spring-beans-5.3.22.jar:5.3.22]
... 17 common frames omitted
Caused by: java.lang.IllegalArgumentException: null
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:64) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:na]
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500) ~[na:na]
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481) ~[na:na]
at com.fasterxml.jackson.databind.introspect.AnnotatedConstructor.call(AnnotatedConstructor.java:126) ~[jackson-databind-2.16.1.jar:2.16.1]
at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromObjectWith(StdValueInstantiator.java:291) ~[jackson-databind-2.16.1.jar:2.16.1]
... 35 common frames omitted
as i mention i've extensively debugged this, to the point i see the code calling the native method for "new instance" and the parameter that is supposed to be exported is set to null