Wrapper object and identity info - deserialization issue with polymorphic collections

806 views
Skip to first unread message

Kevin Chapuis

unread,
Dec 2, 2017, 4:24:02 AM12/2/17
to jackson-user
Hi everyone,

I'd post a question on stack overflow without any success. My problem is fully exposed here

In few words, i am not able to deserialize a collection of polymorphic object. The source of the problem comes from interface annotations:

@JsonTypeInfo(use=Id.NAME, include=As.WRAPPER_OBJECT)
@JsonSubTypes({ 
  @Type(value = Lion.class, name = "LION")
})
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property=IAnimal.NAME)
I have type info for polymorphism and identity info for multiple serialization of the same object. When stored in a collection, the deserializer complain with identity references which are not wrapped in object (as required with type info). Here is the exception i've got:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Unexpected token (VALUE_STRING), expected START_OBJECT: need JSON Object to contain As.WRAPPER_OBJECT type information for class core.configuration.jackson.utilclass.dummy.IAnimal at [Source: (File); line: 1, column: 40] (through reference chain: core.configuration.jackson.utilclass.dummy.Cage["animals"]-

and here is the JSON of the animals collection made of IAnimal in my exemple:

{"animals":[{"LION":{"NAME":"michel"}},"michel"]} 

Thx for the help.
Kevin

Tatu Saloranta

unread,
Dec 14, 2017, 6:45:00 PM12/14/17
to jackson-user
The simplest way to debug things is usually to serialize Object in
question, then deserialize.
But before going into that, one thing you probably want to change is
the use of generic type as root value:
although it is supported and can be made to work, it is a well-known
source for issues. Life will be easier
if the root value is not generic (any type reference from there is fine).

Alternatively, if you absolutely do want additional challenge, you
will need to provide generic type BOTH for
serialization and deserialization: problem being Java Type Erasure
which will otherwise lose generic type
on serialization side.
Specifically, what you think of as `Cage<IAnimal>` can not be detected
as such, but only as `Cage<?>`, when
passing value. On deserialization it is less of a problem as you need
to provide type anyway.

On serialization, 2 main work-arounds (this is FAQ):

1. Create non-generic sub-type, use that (like `class AnimalCage
extend Cage<IAnimal> { .... }`)
2. Create `ObjectWriter` from mapper, with full type (TypeReference,
or JavaType):

mapper.writerFor(new TypeReference<Cage<IAnimal>>() {
}).writeValueAsBytes(cageValue);

Hope this helps,

-+ Tatu +-
> --
> You received this message because you are subscribed to the Google Groups
> "jackson-user" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to jackson-user...@googlegroups.com.
> To post to this group, send email to jackso...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages