Handling polymorphism with Jackson

Sometime you need to serialize a hierarchical model to JSON. Jackson offers different ways to handle the problem. Here I will expose two of them.


First solution: Annotate the super class with @JsonTypeInfo(use=Id.CLASS)Pros: works with any subtype. Cons: breaks with classes or package renaming.

Second solution: Annotate the super class with:

adding a JsonSubTypes.Type for each sub-class. Pros: no problems with renaming if custom names are provided. Cons: requires to specify all the sub-classes in the super-class.

Long story

We have animals:

between them dogs:

and cats:

We try to serialize a cat:

obtaining the following JSON:

But when we try to deserialize it:

we get an exception:

Not good. Looks like Jackson is not able to understand if the JSON refers to a cat or to a dog.

We can help Jackson annotating the super-class with the JsonTypeInfo annotation. The annotation will add type information to the generated JSON.

We can tell Jackson to use the fully-qualified Java class name as type information:

a @class property will be added with the full class name:

If you like a shorter class name you can use the Id.MINIMAL_CLASS option:

a @c property will be added with a shorter class name:

With both solutions we should be worried about refactoring: if we change the classes or package names we will not be able to deserialized previously stored JSON.

As alternative we can store custom names using the Id.NAME option:

Obtaining a JSON with a new property @type with the type name:

By default Jackson uses the class name as name.

Unfortunately during the deserialization we get an exception:

Jackson is not able to map the type name to a class. To solve the problem we provide sub-class information with the JsonSubTypes annotation:

We can use custom names specifying them in the Type annotation:

Now we get a JSON with our custom names:

We can obtain the same result annotating the sub-class with a JsonTypeName annotation:

With custom names we can refactoring without problems but we will need to specify all the subtypes in the super class.

For more information please refer to official documentation: http://wiki.fasterxml.com/JacksonPolymorphicDeserialization

One thought on “Handling polymorphism with Jackson

  1. Ciao

    Ho trovato molto interessante e chiaro il tuo articolo però utilizzando resteasy, jackson e wildfly non riesco a risolvere il problema:
    com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of it.roostech.opipd.beans.Participation, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information
    at [Source: io.undertow.servlet.spec.ServletInputStreamImpl@dd39841; line: 1, column: 18] (through reference chain: it.roostech.opipd.webservices.requests.ParticipationRequest[“participation”])

    Ho provato con la tecnica del name ma pare che non lo riconosca

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload CAPTCHA.