Search code examples
javaxmljacksonfasterxml

Jackson Faster XML: how to parse abstract class' children? Mixins?


We use generated object types from a schema via xcj. Hence, not very flexible control over the types' definitions. We also use JAXB annotations.

Then, we use Jackson Faster XML for deserialization of those objects. Unfortunately, when we deserialize abstract classes, we get an exception:

com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of 
com.x.y.z.AnstractType: abstract types either need to be mapped to concrete types, 
have custom deserializer, or contain additional type information at 
[Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@2989b3db; 
line: 1, column: 625] (through reference chain: com.x.y.z.TypeA["type-b-prop"]->
com.x.y.z.TypeB["type-c-prop"]->java.util.ArrayList[0]->
com.x.y.z.TypeC["abstract-type-prop"]->java.util.ArrayList[0])

The above is solved easily for a single child of the abstract class by adding a mixin:

@JsonTypeInfo(defaultImpl = ChildType.class, use = JsonTypeInfo.Id.MINIMAL_CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
static class AbstractTypeMixIn {
}

and registering it in the object mapper:

objectMapper = new ObjectMapper();
objectMapper.addMixIn(AbstractType.class, AbstractTypeMixIn.class);
...
objectMapper.registerModule(new JaxbAnnotationModule());    

This works like a charm when a single class is inheriting the abstract one. What about multiple children? Any idea how to implement it for more than one inheritants of the abstract class? If not mixins, what else?


Solution

  • The problem was that I was using the mixin only to parse the response, but not to write it. So, the solution was to use the same mixins for the object mappers for both serialization and deserialization. And the following definition was enough:

    @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY)
    static class AbstractTypeMixIn {
    }
    

    It simply adds @type property in JSON for the ambiguous child classes.