Skip to content

Deserialization of @JsonTypeInfo annotated type fails with missing type id even for explicit concrete subtypes #2968

Closed
@kilink

Description

@kilink

When attempting to deserialize to a concrete class that is part of a polymorphic type hierarchy, an InvalidTypeIdException is thrown if the JSON does not contain the type id field. Example:

@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    property = "type")
@JsonSubTypes({
    @JsonSubTypes.Type(value = Foo.class, name = "foo"),
    @JsonSubTypes.Type(value = Bar.class, name = "bar")})
public interface Base {}

public class Foo implements Base {}

public class Bar implements Base {}

ObjectMapper mapper = new ObjectMapper();

mapper.readerFor(Foo.class).readValue("{}"); // throws InvalidTypeIdException
mapper.readValue("{}", Foo.class); // throws InvalidTypeIdException

While I understand why this happens, as Jackson is finding the JsonTypeInfo / JsonSubTypes annotations on the interface, it is counterintuitive to me. In this instance, I am instructing the mapper as to the specific concrete class to deserialize to, so consulting those annotations seems unnecessary. Perhaps checking if the class / type supplied to readerFor / readValue matches exactly one of the classes listed in JsonSubType could be a fallback if the type id property is not found?

So far, the only workaround I've found is to do something like this:

@JsonTypeInfo(use = JsonTypeInfo.Id.NONE)
public class Foo implements Base {}

but then that means serializing a Foo instance would not get the type id property. Perhaps a custom TypeIdResolver or SubTypeResolver could also be used, but having the described behavior baked in seems like a sensible default to me. Thoughts?

Metadata

Metadata

Assignees

No one assigned

    Labels

    most-wantedTag to indicate that there is heavy user +1'ing action

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions