Unable to deserialize collection of concrete subclass when using defaultImpl
See original GitHub issueThis worked in the last 2.7, but is broken in both 2.8.0 and 2.8.5.
I have a field parameterized with a concrete subclass of a base class annotated with @JsonTypeInfo
, and I am trying to deserialize a collection that contains only that specific class. In 2.8.x, the readValue
method fails with com.fasterxml.jackson.databind.JsonMappingException: Class JacksonSubclassCollectionTest$SomeBaseClass not subtype of [simple type, class JacksonSubclassCollectionTest$SomeSubClass]
. This doesn’t appear to happen without defaultImpl
(but I have legacy data with no type
field that I need to be able to keep deserializing in other contexts). Full stack trace follows example.
public class JacksonSubclassCollectionTest {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
SomeContainer container = mapper.readValue("{\"collection\":[{\"type\":\"SUBCLASS\",\"field\":7}]}", SomeContainer.class);
System.out.println(container.collection.get(0).field);
}
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type", defaultImpl = SomeBaseClass.class, visible = true)
@JsonSubTypes({@JsonSubTypes.Type(name = "SUBCLASS", value = SomeSubClass.class)})
public static class SomeBaseClass {
@JsonTypeId
public String type;
}
public static class SomeSubClass extends SomeBaseClass {
public int field;
}
public static class SomeContainer {
public ArrayList<SomeSubClass> collection;
}
}
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Class JacksonSubclassCollectionTest$SomeBaseClass not subtype of [simple type, class JacksonSubclassCollectionTest$SomeSubClass]
at [Source: {"collection":[{"type":"SUBCLASS","field":7}]}; line: 1, column: 1]
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:296)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:269)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142)
at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:475)
at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:3890)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3785)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2833)
at JacksonSubclassCollectionTest.main(JacksonSubclassCollectionTest.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: java.lang.IllegalArgumentException: Class JacksonSubclassCollectionTest$SomeBaseClass not subtype of [simple type, class JacksonSubclassCollectionTest$SomeSubClass]
at com.fasterxml.jackson.databind.type.TypeFactory.constructSpecializedType(TypeFactory.java:359)
at com.fasterxml.jackson.databind.jsontype.impl.StdTypeResolverBuilder.buildTypeDeserializer(StdTypeResolverBuilder.java:118)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.findTypeDeserializer(BasicDeserializerFactory.java:1363)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.findPropertyContentTypeDeserializer(BasicDeserializerFactory.java:1526)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.resolveMemberAndTypeAnnotations(BasicDeserializerFactory.java:1841)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.constructSettableProperty(BeanDeserializerFactory.java:735)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.addBeanProps(BeanDeserializerFactory.java:520)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer(BeanDeserializerFactory.java:226)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:141)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:406)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:352)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264)
... 12 more
Issue Analytics
- State:
- Created 7 years ago
- Reactions:1
- Comments:6 (3 by maintainers)
Top Results From Across the Web
Jackson deserialization to concrete polymorphic class
There's a default implementation class to use for deserialization via defaultImpl : @JsonTypeInfo(use = JsonTypeInfo.
Read more >Using @JsonTypeInfo and @JsonSubTypes, Deserialize an ...
I have found a solution. You need to enable MapperFeature.USE_BASE_TYPE_AS_DEFAULT_IMPL in order to directly deserialize the object using concrete subclass ...
Read more >How To Deserialize Subclasses Using ObjectMapper
Deserialize JSON to the abstract class using Its child classes or deserialize in subclasses using Jackson Object mapper.
Read more >Deserializing an interface with Jackson | Andrew Tarry
Using Java and json together can make it hard to manage deserialisation correctly when using interfaces. Here we show the solution to 3...
Read more >SUSE-SU-2022:1678-1: important: Security update for jackson ...
READ_ONLY' fails with collections when a property name is specified + ... thrown for mismatched subclass deserialization + Add convenience ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Guys, this is a BIG regression for people upgrading from 2.7.
If you have some class with a List<> and another with a Set<>, using a SimpleAbstractTypeResolver that provides the defaultImpl as ArrayList and HashSet, it just does NOT work anymore.
Look like this is fixed by https://github.com/FasterXML/jackson-databind/issues/1565. At least updating to 2.9.6 fixed same issue for me.