Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deserialize with multiple levels of polymorphic type hierachy #374

Closed
joseph2002 opened this issue Dec 25, 2013 · 7 comments
Closed

Deserialize with multiple levels of polymorphic type hierachy #374

joseph2002 opened this issue Dec 25, 2013 · 7 comments

Comments

@joseph2002
Copy link

It seems that this use case is not supported:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonSubTypes({
    @JsonSubTypes.Type(value=B1.class, name="b1"),
    @JsonSubTypes.Type(value=B2.class, name="b2")
})
public abstract class A {
    ...
}

public class B1 extends A {
    ...
}

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "subtype")
@JsonSubTypes({
    @JsonSubTypes.Type(value=C1.class, name="c1"),
    @JsonSubTypes.Type(value=C2.class, name="c2")
})
public abstract class B2 extends A {
    ...
}

public class C1 extends B2 {
    ...
}

public class C2 extends B2 {
    ...
}

What I want is to resolve this one: { "type": "b1"; ... } to class B1, and { "type": "b2"; "subtype": "c1"; ... } to class C1 and { "type": "b2"; "subtype": "c2"; ... } to class C2. (B1 has no "subtype" property, while C1 and C2 have the same "type" property and different "subtype" property)
Any suggestions?

@cowtowncoder
Copy link
Member

This is not supported and there are no plans to extend type resolution in this direction. Technically it will be challenging to try to do this using standard resolution mechanism due to need to correlated values of multiple properties, so your best bet is probably fully custom serializers and deserializers.

@umbreak
Copy link

umbreak commented Apr 11, 2014

So then, what is supported through those annotations is just one level polymorphism?
I think the case described is quite common:

class Animal{...}
class Bird extends Animal {...}
class Mammal extends Animal {...}
class Zebra extends Mammal{...}
class Tiger extends Mammal{...}

The only way to support that would be through custom serialization? Like here: https://gist.github.com/s-j/8864592 ?

EDIT:
That actually works:

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "className")
public class Animal {
    private String title;
}

public class Bird extends Animal {
    private Integer airSpeed;
}

@JsonSubTypes({
    @JsonSubTypes.Type(value = Tiger.class, name = "tiger"),
    @JsonSubTypes.Type(value = Zebra.class, name = "zebra")})
public class Mammal extends Animal {
    private Integer legs;
}

public class Tiger extends Mammal {
    private String whateverForTiger;
}

public class Zebra extends Mammal {
    private String whateverForZebra;
}

@cowtowncoder
Copy link
Member

No, full inheritance is supported, but you can not use separate type discriminator properties: it is not possible to use, say "type" AND "subtype" -- you must use just one like "type". Subtype dependencies may be defined in chaining fashion as you mentioned (from parent to intermediate subtype; from intermediate subtype to further subtypes).

@jamarillo
Copy link

jamarillo commented Sep 14, 2016

I have a similar problem, i have 3 class, abstract class generic (), class class1 extends generic() and class11 extends class1() :

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({@JsonSubTypes.Type(value=CardActivityTable.class, name="5") })
@Document(collection = Card.COLLECTION_NAME)
public abstract class Card extends AuditableEntity {
}

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "typeActivity")
@JsonSubTypes({ @JsonSubTypes.Type(value = CardActivity.class, name = 3) })
@Document(collection = Card.COLLECTION_NAME)

public class CardActivityTable extends Card {
}

@Document(collection = Card.COLLECTION_NAME)
public class CardActivity extends CardActivityTable {
   public String optionC;
}

I'm trying to insert the json:

{
"type":"5",
"typeActivity": "3",
"optionC": "test"
}

but i show the error :

"Could not read document: Unrecognized field "optionC"

@cowtowncoder
Copy link
Member

@jamarillo possibly -- and as you noticed, support for multi-level resolution does not exist nor is planned. So chaining of definitions will not work.

@hrishikesh-kumar
Copy link

@cowtowncoder
This post is around 4 years old, now is there any update on this? Because I fell it's a basic use-case. Do we have any workaround. I'm designing my classes on composite design pattern and facing this issue.

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "componentType", visible = true)
@JsonSubTypes({
        @JsonSubTypes.Type(value = ElementGroup.class, name = "ELEMENT_GROUP"),
        @JsonSubTypes.Type(value = Element.class, name = "ELEMENT")})
public abstract class Component {
    private String id;
    private String displayName;
    private DisplayOrientation displayOrientation;
    private Map<String, String> properties;
    private ComponentType componentType;
}
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "provider" , visible = true)
@JsonSubTypes({
        @JsonSubTypes.Type(value = AMElementGroup.class, name = "AM")}
)
public abstract class ElementGroup extends Component {
    private ElementProvider provider;
    private List<Component> children;
}
public class AMElementGroup extends ElementGroup {
    private TimeFilterConfig timeFilterConfig;
    private List<Aggregate> allowedAggregates;
}

I tried custom JsonDeserialize but didn't work.

Waiting for response.

@cowtowncoder
Copy link
Member

@hrishikesh-kumar It is not supported and there are no plans to support it. Do not design your system assuming this will be implemented.

And I have no idea what " tried custom JsonDeserialize but didn't work." means -- custom deserializers can support LITERALLY anything.

@FasterXML FasterXML locked and limited conversation to collaborators Jan 10, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants