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