Skip to content

First element in unwrapped XML array is ignored during deserialization to base class #567

Open
@tetradon

Description

@tetradon

During Jackson migration, I discovered an issue that looks like a regression in 2.11.1. In this version, the first element in XML array is ignored when I deserialize to the base class.

@JsonSubTypes({
        @JsonSubTypes.Type(value = Wrapper.class, name = "wrapper")
})
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Base {
}
@JacksonXmlRootElement(localName = "wrapper")
public class Wrapper extends Base {

    @JacksonXmlProperty(localName = "item")
    @JacksonXmlElementWrapper(useWrapping = false)
    private List<Item> items = new ArrayList<>();

    public Wrapper(List<Item> items) {
        this.items = items;
    }

    public Wrapper() {
    }

    public List<Item> getItems() {
        return items;
    }

    public void setItems(List<Item> items) {
        this.items = items;
    }

    @Override
    public String toString() {
        return "Wrapper{" +
                "items=" + items +
                '}';
    }
}
@JacksonXmlRootElement(localName = "item")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class Item {

    private String id;

    public Item(String id) {
        this.id = id;
    }

    public Item() {
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "Item{" +
                "id='" + id + '\'' +
                '}';
    }
}
public class Main {
    public static void main(String[] args) throws JsonProcessingException {
        String xmlString = """
                <?xml version="1.0" encoding="UTF-8"?>
                <wrapper type="wrapper">
                    <item><id>1</id></item>
                    <item><id>2</id></item>
                    <item><id>3</id></item>
                </wrapper>
                """;
        Base base = new XmlMapper().readValue(xmlString, Base.class);
        System.out.println(base);
    }
}

Output:

Version 2.11.0
image

Version 2.11.1+
image

Workarounds:

  1. Deserizalize to the concrete Wrapper class instead of Base:
    new XmlMapper().readValue(xmlString, Wrapper.class);
  2. Add following setter for the Wrapper class
   @JsonSetter
   public void setItems(Item item) {
        this.items.add(item);
    }

Unofortunately workarounds doesn't suit my needs as this is library code base that is used in many other projects :(

Link to the code in GitHub:
https://github.com/tetradon/jackson-xml-deserialization-issue

Metadata

Metadata

Assignees

No one assigned

    Labels

    has-failing-testIndicates that there exists a test case (under `failing/`) to reproduce the issue

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions