Description
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?