6

I am using Jackson's @JsonIdentityInfo annotation to generate nice object graphs.

I have the following object (which is a hibernate entity also):

@Entity
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, 
                   property="id")
public class MemberFieldDef implements Def
{
    @Id @GeneratedValue(generator="myGen")
    private String id;

   ....
}

This class works fine during serialization, when part of an object graph, but when I want to submit a new, transient entity through Jackson, which doesn't have an ID yet and has

{
    "id":null,
    ...
}

The deserialization fails with:

com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of VALUE_NULL token
 at [Source: java.io.PushbackInputStream@5950054d; line: 1, column: 2] (through reference chain: net._95point2.sarbase.cohort.entity.MemberFieldDef["id"])
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)
    at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:762)
    at com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:59)
    at com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:12)
    at com.fasterxml.jackson.databind.deser.impl.ObjectIdValueProperty.deserializeSetAndReturn(ObjectIdValueProperty.java:90)
    at com.fasterxml.jackson.databind.deser.impl.ObjectIdValueProperty.deserializeAndSet(ObjectIdValueProperty.java:82)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:306)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeWithObjectId(BeanDeserializerBase.java:1036)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:122)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3066)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2221)
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:205)

The stacktrace shows that Jackson is not using the regular StringDeserializer - which returns null for a literal null - but is using the ObjectIdValueProperty which doesn't seem to permit nulls.

Is there a solution for transient objects?

Rob Shepherd
  • 866
  • 1
  • 9
  • 25

2 Answers2

1

We fixed it using the solution provided here, using JsonInclude:

@JsonInclude(Include.NON_NULL)
public class Shop {
    //...
}

Hope it works for you as well!

Community
  • 1
  • 1
Leo Lozes
  • 1,358
  • 1
  • 15
  • 33
0

I know this one is question, but I was able to resolve this issue by coding the getter that returned target object to the something like:

    public MemberFieldDef getMemberFieldDef() {
       return (this.memberFieldDef == null || this.memberFieldDef.getId() == null)?null:this.memberFieldDef;
    }

Also, make sure your equals/hashCode accounts for null values if your using the ID as a part of the hashCode.

rwblackburn
  • 371
  • 3
  • 13