javadeserializationjackson-dataformat-xml

How can I resolve jackson deserialization error while using java.util.List?


I am facing with the below error:

com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve type id 'accounts' as a subtype of `java.util.List<Account>`: no such class found at [Source: (StringReader); line: 48, column: 11] (through reference chain: >Partner["accounts"])

while using XmlMapper. How can I fix it?

Here is my attempt so far:

@JsonIdentityInfo(
        generator = ObjectIdGenerators.PropertyGenerator.class,
        property = "databaseId")
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonSubTypes({
        @JsonSubTypes.Type(value = java.util.List.class, name = "accounts")
})
public class Partner{
private List<Account> accounts;
@JsonManagedReference
    public void setAccounts(List<Account> accounts) {
        this.accounts = accounts;
    }}


These are my mapper configurations:

mapper.activateDefaultTyping(mapper.getPolymorphicTypeValidator(),ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_OBJECT);
mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS z");
df.setTimeZone(TimeZone.getTimeZone("UTC"));
mapper.setDateFormat(df);
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

Solution

  • I was able to resolve this using jackson MixIns. The problem was that, jackson was unable to resolve java.util.ArrayList as a subtype of java.util.List as accounts was being created as an instance of ArrayList and serialized so in the XML.

    The @JsonSubTypes annotations allows to annotate the interface/abstract class with their implementation types to let jackson know what the concrete implementations are going to be.

    In this case, I cannot add this annotation directly to java.util.List as it is a library provided class.

    For usecases like this, we can use MixIn classes, and I have demonstrated them with an example below

    1. Create a MixIn for List and register ArrayList as a valid sub-type
    @JsonTypeInfo(use = JsonTypeInfo.Id.NONE, property = "type")
    @JsonSubTypes({
            @JsonSubTypes.Type(value = ArrayList.class)
    })
    public abstract class ListMixin{
        @JsonCreator
        public ListMixin() {}
    
    }
    
    1. On your mapper configurations, add the mixin for the target class as below mapper.addMixIn(List.class, ListMixin.class);