JacksonDeserializer fails when json lacks a boolean property

60 Views Asked by At

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

0

There are 0 best solutions below