RE: [jackson-user] Binding polymorphic type discriminator as deserialized property

1,844 views
Skip to first unread message

Paul R Brown

unread,
Aug 27, 2013, 2:42:08 AM8/27/13
to Jones, Nathan, jackso...@googlegroups.com, us...@jackson.codehaus.org

Hi, Nathan --

(Note that I've redirected the conversation to the Google Group.  We're trying to get things moved over without anyone getting lost on the way.)

Can you post a bit more about your runtime configuration?  Your situation makes me suspicious that you've got Jackson v1 registered in the JAX-RS side of things but Jackson v2 annotations.

Better, faster JSON and XML for the JVM platform.

On August 26, 2013 at 10:08:17 PM, Jones, Nathan (nathan...@airnz.co.nz) wrote:

I am not too concerned about the behaviour with arrays because in reality I am only using collections. However, now I am seeing the same differences between JSON serialised in my unit tests and JSON serialised by JAX-RS. Here is a complete working example (assuming you have a JAX-RS runtime with com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider registed):

import java.util.Arrays;
import java.util.List;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
import com.fasterxml.jackson.annotation.JsonTypeId;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
import com.fasterxml.jackson.annotation.JsonTypeName;
import com.fasterxml.jackson.databind.ObjectMapper;

@Path("animals")
public class AnimalResource {

@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Animal> animals() {
return createAnimals();
}

public static List<Animal> createAnimals() {
Dog dog = new Dog();
dog.name = "Scooby";
Elephant elephant = new Elephant();
elephant.name = "Dumbo";
GenericAnimal camel = new GenericAnimal();
camel.name = "Alice";
camel.setType("camel");
return Arrays.asList(dog, elephant, camel);
}

public static void main(String[] args) throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(createAnimals());
System.out.println(json);
}

@JsonTypeInfo(use = Id.NAME, property = "type", visible = true, defaultImpl = GenericAnimal.class)
@JsonSubTypes({ @Type(Elephant.class), @Type(Dog.class) })
public static abstract class Animal
{

@JsonTypeId
public String getType()
{
JsonTypeName annotation = this.getClass().getAnnotation(JsonTypeName.class);
return annotation.value();
}

public String name;
}

@JsonTypeName("elephant")
public static class Elephant
extends Animal
{
}

@JsonTypeName("dog")
public static class Dog
extends Animal
{
}

public static class GenericAnimal
extends Animal
{

private String type;

@Override
public String getType()
{
return type;
}

public void setType(String type)
{
this.type = type;
}

}

}

In the above example the output of the main method is:

[{"name":"Scooby"},{"name":"Dumbo"},{"name":"Alice"}]

The body of the HTTP response for requesting "GET /animals" is:

[{"type":"dog","name":"Scooby"},{"type":"elephant","name":"Dumbo"},{"type":"camel","name":"Alice"}]

I can't figure out what is causing these differences in serialisation. Is the JacksonJsonProvider doing something to reconfigure the object mapper?

- Nathan

________________________________________
From: Tatu Saloranta [mailto:tsalo...@gmail.com]
Sent: Tuesday, 27 August 2013 9:13 a.m.
To: us...@jackson.codehaus.org
Subject: Re: [jackson-user] Binding polymorphic type discriminator as deserialized property


On Sun, Aug 25, 2013 at 10:35 PM, Jones, Nathan <Nathan...@airnz.co.nz> wrote:
I am seeing some strange differences with the handling of the type info between polymorphic collections and polymorphic arrays. When the @JsonTypeId annotation is present on the getType() method then an array of Animal will be serialised with the "type" property as expected but a List of animal will be serialized with no "type" property and then cannot be deserialized. When the @JsonTypeId annotation is missing on the getType() method then a List of animal will be serialized with the "type" property as expected but an array of Animal will be serialized with the "type" property included twice; the values are identical for the "known" sub types but for the defaultImpl one of the values is the simple name of the class.

Is this a bug?

Without sample code I can't say, but keep in mind that JVM's handling of arrays and Collections differs radically: arrays are about the only things that retain full non-type-erased information. Collections (and are other generic objects) lose their type information more easily.
This explains many observed differences.
Are than this, handling by Jackson should be similar, once type information has been resolved.

-+ Tatu +-
 


Good planets are hard to find - please think of the environment before you print this email.
____________________________________________________________________
CAUTION - This message may contain privileged and confidential
information intended only for the use of the addressee named above.
If you are not the intended recipient of this message you are hereby
notified that any use, dissemination, distribution or reproduction
of this message is prohibited. If you have received this message in
error please notify Air New Zealand immediately. Any views expressed
in this message are those of the individual sender and may not
necessarily reflect the views of Air New Zealand.
_____________________________________________________________________
For more information on the Air New Zealand Group, visit us online
at http://www.airnewzealand.com
_____________________________________________________________________


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email


Karl Koster

unread,
Oct 21, 2014, 8:33:53 AM10/21/14
to jackso...@googlegroups.com, nathan...@airnz.co.nz, us...@jackson.codehaus.org
Any movement on this issue? I have run into a similar problem when serializing/deserializing collections using 2.3.2. 

I have annotated an abstract base class with @JsonTypeInfo identifying a property as the discriminator and tagging it as visible. 
I also have a JsonSubTypes annotation on the same base class with two classes and the name of the value for the property in question. 

I am serializing a List type extended from ArrayList with the base type as the generic for the ArrayList subclass. When it is serialized, the discriminator property is showing up twice in the JSON. The resulting JSON will deserialize into the identical list. So, functionally this works. However, I am also providing JSON schema validation and the generated JSON fails when checked against the schema (duplicate property).

I have tried various combinations of annotations (e.g. a getter returning a constant and shutting off visibility) with varying degrees of success. I would just like to serialize/deserialize a set of subtypes discriminated by a property of the POJO without having to jump through so many hoops. 

Any constructive direction would be appreciated.

Thanks,
Karl

Tatu Saloranta

unread,
Oct 21, 2014, 2:11:18 PM10/21/14
to jackso...@googlegroups.com, nathan...@airnz.co.nz, us...@jackson.codehaus.org
Yes, there is some progress in master (for 2.5.0), as inclusion of `As.EXISTING_PROPERTY` is now supported (issue #528).
That should help avoid writing of property twice. So you could try with a local 2.5.0-SNAPSHOT build.

-+ 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.

Kris Glover

unread,
Nov 24, 2014, 4:15:01 PM11/24/14
to jackso...@googlegroups.com, nathan...@airnz.co.nz, us...@jackson.codehaus.org
I couldn't find a release schedule anywhere and was wondering if you knew about when 2.5.0 would be released ? I've tested the 2.5.0-SNAPSHOT locally and it's working great but I just want to be able to drop the snapshot since my project forbids (for obvious reasons) SNAPSHOTs in our builds. 

Thanks!
Kris

Kris Glover

unread,
Nov 24, 2014, 4:20:10 PM11/24/14
to jackso...@googlegroups.com, nathan...@airnz.co.nz, us...@jackson.codehaus.org
I'm running into the same issue. 2.5.0-SNAPSHOT seems to do the trick. Would you happen to have a rough idea when 2.5.0 will be officially released? 

Thanks
Kris

On Tuesday, October 21, 2014 2:11:18 PM UTC-4, Tatu Saloranta wrote:

Tatu Saloranta

unread,
Nov 24, 2014, 7:31:11 PM11/24/14
to jackso...@googlegroups.com, nathan...@airnz.co.nz, us...@jackson.codehaus.org
We do not have strict timeline, releases are done "when they are ready".
That said, I think we are closing on 2.5.0 feature set, and can hopefully start with a release candidate within next 2 weeks or so.
So it is possible that the official 2.5.0 could be out before christmas.

-+ Tatu +-

Kris Glover

unread,
Nov 24, 2014, 10:11:05 PM11/24/14
to jackso...@googlegroups.com, nathan...@airnz.co.nz, us...@jackson.codehaus.org
Thanks a lot and I apologize for the double post. I thought my initial one didn't post but it was just waiting for approval. I'll keep that in mind for next time.
Reply all
Reply to author
Forward
0 new messages