Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deserializing nested polymorphic property does not work if defaultImpl is specified #1614

Closed
jhorstmann opened this issue Apr 26, 2017 · 1 comment

Comments

@jhorstmann
Copy link

Using jackson 2.8.8, the following test case fails (exception stacktrace below), but succeeds if removing the defaultImpl = Unknown.class configuration:

public class PolymorphicDeserialiationTest {
    @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type", visible = true, defaultImpl = Unknown.class)
    public interface Parent {
    }

    public static class Unknown implements Parent {
    }

    @JsonTypeName("A")
    public static class A implements Parent {
    }

    @JsonTypeName("B")
    public static class B implements Parent {
        public A a;
    }

    @Test
    public void shouldDeserializeNestedPolymorphicProperty() throws IOException {
        final ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerSubtypes(Parent.class, A.class, B.class, Unknown.class);
        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

        final Parent parent = objectMapper.readValue("{\"type\":\"B\",\"a\":{\"type\":\"A\"}}", Parent.class);

        Assert.assertEquals(B.class, parent.getClass());
    }
}

The exception is:

com.fasterxml.jackson.databind.JsonMappingException: Class PolymorphicDeserialiationTest$Unknown not subtype of [simple type, class PolymorphicDeserialiationTest$A]
 at [Source: {"type":"B","a":{"type":"A"}}; line: 1, column: 9]
        at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:305)
        at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:268)
        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.findContextualValueDeserializer(DeserializationContext.java:443)
        at com.fasterxml.jackson.databind.jsontype.impl.TypeDeserializerBase._findDeserializer(TypeDeserializerBase.java:188)
        ...
Caused by: java.lang.IllegalArgumentException: Class PolymorphicDeserialiationTest$Unknown not subtype of [simple type, class PolymorphicDeserialiationTest$A]
        at com.fasterxml.jackson.databind.type.TypeFactory.constructSpecializedType(TypeFactory.java:359)
        at com.fasterxml.jackson.databind.jsontype.impl.StdTypeResolverBuilder.buildTypeDeserializer(StdTypeResolverBuilder.java:128)
        at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.findTypeDeserializer(BasicDeserializerFactory.java:1372)
        at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.findPropertyTypeDeserializer(BasicDeserializerFactory.java:1507)
        at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.resolveMemberAndTypeAnnotations(BasicDeserializerFactory.java:1856)
        at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.constructSettableProperty(BeanDeserializerFactory.java:742)
        at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.addBeanProps(BeanDeserializerFactory.java:521)
        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:403)
        at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:349)
        at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264)
        ... 37 more
@cowtowncoder
Copy link
Member

I think this would be resolved by #1358.

I am bit torn here; I think usage of trying to specify A as type, when real basetype is Parent is not something that should be used, and conceptually not something that is supported. Polymorphic base types ought to be compatible.
However due to annotation inheritance it is true that @JsonTypeInfo is visible and it is not unreasonable to expect that that should work (at least unless sub-class tries to redefine settings or subtype names).

So: I hope this can be improved in future; but in the meantime combination of different base types is not supported, so changing type of property a as Parent is the recommended fix.

@cowtowncoder cowtowncoder closed this as not planned Won't fix, can't repro, duplicate, stale May 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants