-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Closed
Milestone
Description
Test model:
public static interface F1 {}
public static class A implements F1 {
public String a;
}
public static class B implements F1 {
public String b;
}
public static interface F2 {}
public static class C implements F2 {
public String c;
}
public static class D implements F2{
public String d;
}
public static class Container {
public String type;
@JsonTypeInfo(use = Id.NAME, property = "type", include = As.EXTERNAL_PROPERTY)
@JsonSubTypes({
@JsonSubTypes.Type(value = A.class, name = "1"),
@JsonSubTypes.Type(value = B.class, name = "2")})
public F1 field1;
@JsonTypeInfo(use = Id.NAME, property = "type", include = As.EXTERNAL_PROPERTY)
@JsonSubTypes({
@JsonSubTypes.Type(value = C.class, name = "1"),
@JsonSubTypes.Type(value = D.class, name = "2")})
public F2 field2;
}
Test JSON:
{
"type" : "1",
"field1" : {
"a" : "AAA"
},
"field2" : {
"c" : "CCC"
}
}
Stacktrace:
com.fasterxml.jackson.databind.JsonMappingException: Unexpected token (VALUE_NULL), expected VALUE_STRING: need JSON String that contains type id (for subtype of F2)
at [Source: java.io.StringReader@b2fe7658; line: 9, column: 1]
at com.fasterxml.jackson.databind.DeserializationContext.wrongTokenException(DeserializationContext.java:668)
at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer._locateTypeId(AsArrayTypeDeserializer.java:144)
at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer._deserialize(AsArrayTypeDeserializer.java:101)
at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer.deserializeTypedFromObject(AsArrayTypeDeserializer.java:69)
at com.fasterxml.jackson.databind.deser.AbstractDeserializer.deserializeWithType(AbstractDeserializer.java:106)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:462)
at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:107)
at com.fasterxml.jackson.databind.deser.impl.ExternalTypeHandler._deserializeAndSet(ExternalTypeHandler.java:253)
at com.fasterxml.jackson.databind.deser.impl.ExternalTypeHandler.complete(ExternalTypeHandler.java:162)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeWithExternalTypeId(BeanDeserializer.java:715)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeWithExternalTypeId(BeanDeserializer.java:664)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:274)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2888)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2034)
The reason:
com.fasterxml.jackson.databind.deser.impl.ExternalTypeHandler:262
public static class Builder
{
private final ArrayList<ExtTypedProperty> _properties = new ArrayList<ExtTypedProperty>();
private final HashMap<String, Integer> _nameToPropertyIndex = new HashMap<String, Integer>();
// note: signature changed between 2.1.0 and 2.1.1 (alas!)
public void addExternal(SettableBeanProperty property, TypeDeserializer typeDeser)
{
Integer index = _properties.size();
_properties.add(new ExtTypedProperty(property, typeDeser));
_nameToPropertyIndex.put(property.getName(), index);
_nameToPropertyIndex.put(typeDeser.getPropertyName(), index);
}
addExternal() method is called in property loop, but _nameToPropertyIndex is Map, so addExternal() can't be called twice correctly for property "type".
So _nameToPropertyIndex doesn't contain type=0: {field1=1, type=1, field2=0}
I think type of _nameToPropertyIndex should be changed from HashMap[String, Integer] to HashMap[String, Set[Integer]]. It occurs several changes in ExternalTypeHandler. I've patched jar locally and it solved my problem.
Metadata
Metadata
Assignees
Labels
No labels