Is your feature request related to a problem? Please describe.
Currently we cannot use forward references together with a @JsonCreator. See the following example:
class A1 {
public List<B> bs;
public List<C1> cs;
}
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
class B {
public String id;
}
class C1 {
private B b;
@JsonCreator
public C1(@JsonProperty("b") B b) {
this.b = b;
}
@JsonGetter("b")
public B getB() {
return b;
}
}
class C2 {
public B b;
}
class A2 {
public List<B> bs;
public List<C2> cs;
}
public class Main {
public static void main(final String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
A1 a2 = mapper.readValue("{\"bs\":[{\"id\":\"b1\"},{\"id\":\"b2\"}],\"cs\":[{\"b\":\"b1\"},{\"b\":\"b2\"}]}", A1.class);
System.out.println("Using correct ordered data (no forward references) with JsonCreator works");
A2 a3 = mapper.readValue("{\"cs\":[{\"b\":\"b1\"},{\"b\":\"b2\"}],\"bs\":[{\"id\":\"b1\"},{\"id\":\"b2\"}]}", A2.class);
System.out.println("Using incorrect ordered data (with forward references) with no JsonCreator works");
A1 a4 = mapper.readValue("{\"cs\":[{\"b\":\"b1\"},{\"b\":\"b2\"}],\"bs\":[{\"id\":\"b1\"},{\"id\":\"b2\"}]}", A1.class);
}
}
The first two deserializations work as expected but the third one, where we use forward references and the @JsonCreator throws an exception.
This is the output when running the above code snippet:
Using correct ordered data (no forward references) with JsonCreator works
Using incorrect ordered data (with forward references) with no JsonCreator works
Exception in thread "main" com.fasterxml.jackson.databind.deser.UnresolvedForwardReference: Could not resolve Object Id [b1] (for [simple type, class B]).
at [Source: (String)"{"cs":[{"b":"b1"},{"b":"b2"}],"bs":[{"id":"b1"},{"id":"b2"}]}"; line: 1, column: 17] (through reference chain: A1["cs"]->java.util.ArrayList[0]->C1["b"])
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectId(BeanDeserializerBase.java:1292)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromString(BeanDeserializerBase.java:1381)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:176)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:166)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:542)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeWithErrorWrapping(BeanDeserializer.java:535)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:419)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1310)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:331)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:164)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:285)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:244)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:27)
at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:138)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:293)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:156)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4482)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3434)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3402)
at Main.main(Main.java:52)
Describe the solution you'd like
Lazily call @JsonCreator for such objects only after the whole json (and all objects with ids) got read.
Usage example
See my example above.
Is your feature request related to a problem? Please describe.
Currently we cannot use forward references together with a
@JsonCreator. See the following example:The first two deserializations work as expected but the third one, where we use forward references and the
@JsonCreatorthrows an exception.This is the output when running the above code snippet:
Describe the solution you'd like
Lazily call
@JsonCreatorfor such objects only after the whole json (and all objects with ids) got read.Usage example
See my example above.