Search before asking

  • [x] I searched in the issues and found nothing similar.

Describe the bug

The following deserialization worked in 2.18.4 but no longer works in 2.19+ (I tried both 2.19.0 and 2.19.1).

Version Information

2.19.0/2.19.1

Reproduction

import static org.assertj.core.api.Assertions.assertThat;

import java.util.List;
import java.util.Map;

import org.junit.jupiter.api.Test;

import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class TestTest {
    @Test
    public void test() throws JsonProcessingException {
        final ObjectMapper mapper = new ObjectMapper();
        final CollectionType type = CollectionType.builder().name("name")
                .items(List
                        .of(Item.builder().type("type").attributes(Map.of("key", "value", "key2", "value2")).build()))
                .build();
        final String json = mapper.writeValueAsString(type);
        System.out.println(json);
        final CollectionType serialized = mapper.readValue(json, CollectionType.class);
        assertThat(serialized.getItems().get(0).getAttributes()).isNotNull();
    }

    @com.fasterxml.jackson.databind.annotation.JsonDeserialize(
            builder = TestTest.CollectionType.CollectionTypeBuilder.class)
    public static class CollectionType {
        private String name;
        private List<Item> items;

        @java.lang.SuppressWarnings("all")
        @lombok.Generated
        @com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder(withPrefix = "", buildMethodName = "build")
        public static class CollectionTypeBuilder {
            @java.lang.SuppressWarnings("all")
            @lombok.Generated
            private String name;
            @java.lang.SuppressWarnings("all")
            @lombok.Generated
            private List<Item> items;

            @java.lang.SuppressWarnings("all")
            @lombok.Generated
            CollectionTypeBuilder() {
            }

            /**
             * @return {@code this}.
             */
            @java.lang.SuppressWarnings("all")
            @lombok.Generated
            public TestTest.CollectionType.CollectionTypeBuilder name(final String name) {
                this.name = name;
                return this;
            }

            /**
             * @return {@code this}.
             */
            @java.lang.SuppressWarnings("all")
            @lombok.Generated
            public TestTest.CollectionType.CollectionTypeBuilder items(final List<Item> items) {
                this.items = items;
                return this;
            }

            @java.lang.SuppressWarnings("all")
            @lombok.Generated
            public TestTest.CollectionType build() {
                return new TestTest.CollectionType(this.name, this.items);
            }

            @java.lang.Override
            @java.lang.SuppressWarnings("all")
            @lombok.Generated
            public java.lang.String toString() {
                return "TestTest.CollectionType.CollectionTypeBuilder(name=" + this.name + ", items=" + this.items
                        + ")";
            }
        }

        @java.lang.SuppressWarnings("all")
        @lombok.Generated
        public static TestTest.CollectionType.CollectionTypeBuilder builder() {
            return new TestTest.CollectionType.CollectionTypeBuilder();
        }

        @java.lang.SuppressWarnings("all")
        @lombok.Generated
        public String getName() {
            return this.name;
        }

        @java.lang.SuppressWarnings("all")
        @lombok.Generated
        public List<Item> getItems() {
            return this.items;
        }

        @java.lang.SuppressWarnings("all")
        @lombok.Generated
        public void setName(final String name) {
            this.name = name;
        }

        @java.lang.SuppressWarnings("all")
        @lombok.Generated
        public void setItems(final List<Item> items) {
            this.items = items;
        }

        @java.lang.Override
        @java.lang.SuppressWarnings("all")
        @lombok.Generated
        public boolean equals(final java.lang.Object o) {
            if (o == this) {
                return true;
            }
            if (!(o instanceof TestTest.CollectionType)) {
                return false;
            }
            final TestTest.CollectionType other = (TestTest.CollectionType) o;
            if (!other.canEqual(this)) {
                return false;
            }
            final java.lang.Object this$name = this.getName();
            final java.lang.Object other$name = other.getName();
            if (this$name == null ? other$name != null : !this$name.equals(other$name)) {
                return false;
            }
            final java.lang.Object this$items = this.getItems();
            final java.lang.Object other$items = other.getItems();
            if (this$items == null ? other$items != null : !this$items.equals(other$items)) {
                return false;
            }
            return true;
        }

        @java.lang.SuppressWarnings("all")
        @lombok.Generated
        protected boolean canEqual(final java.lang.Object other) {
            return other instanceof TestTest.CollectionType;
        }

        @java.lang.Override
        @java.lang.SuppressWarnings("all")
        @lombok.Generated
        public int hashCode() {
            final int PRIME = 59;
            int result = 1;
            final java.lang.Object $name = this.getName();
            result = result * PRIME + ($name == null ? 43 : $name.hashCode());
            final java.lang.Object $items = this.getItems();
            return result * PRIME + ($items == null ? 43 : $items.hashCode());
        }

        @java.lang.Override
        @java.lang.SuppressWarnings("all")
        @lombok.Generated
        public java.lang.String toString() {
            return "TestTest.CollectionType(name=" + this.getName() + ", items=" + this.getItems() + ")";
        }

        @java.lang.SuppressWarnings("all")
        @lombok.Generated
        public CollectionType() {
        }

        @java.lang.SuppressWarnings("all")
        @lombok.Generated
        public CollectionType(final String name, final List<Item> items) {
            this.name = name;
            this.items = items;
        }
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    @com.fasterxml.jackson.databind.annotation.JsonDeserialize(builder = TestTest.Item.ItemBuilder.class)
    public static class Item {
        private String type;
        @JsonAnyGetter
        @JsonAnySetter
        private Map<String, Object> attributes;

        @java.lang.SuppressWarnings("all")
        @lombok.Generated
        @JsonIgnoreProperties(ignoreUnknown = true)
        @com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder(withPrefix = "", buildMethodName = "build")
        public static class ItemBuilder {
            @java.lang.SuppressWarnings("all")
            @lombok.Generated
            private String type;
            @java.lang.SuppressWarnings("all")
            @lombok.Generated
            private Map<String, Object> attributes;

            @java.lang.SuppressWarnings("all")
            @lombok.Generated
            ItemBuilder() {
            }

            /**
             * @return {@code this}.
             */
            @java.lang.SuppressWarnings("all")
            @lombok.Generated
            public TestTest.Item.ItemBuilder type(final String type) {
                this.type = type;
                return this;
            }

            /**
             * @return {@code this}.
             */
            @java.lang.SuppressWarnings("all")
            @lombok.Generated
            public TestTest.Item.ItemBuilder attributes(final Map<String, Object> attributes) {
                this.attributes = attributes;
                return this;
            }

            @java.lang.SuppressWarnings("all")
            @lombok.Generated
            public TestTest.Item build() {
                return new TestTest.Item(this.type, this.attributes);
            }

            @java.lang.Override
            @java.lang.SuppressWarnings("all")
            @lombok.Generated
            public java.lang.String toString() {
                return "TestTest.Item.ItemBuilder(type=" + this.type + ", attributes=" + this.attributes + ")";
            }
        }

        @java.lang.SuppressWarnings("all")
        @lombok.Generated
        public static TestTest.Item.ItemBuilder builder() {
            return new TestTest.Item.ItemBuilder();
        }

        @java.lang.SuppressWarnings("all")
        @lombok.Generated
        public String getType() {
            return this.type;
        }

        @java.lang.SuppressWarnings("all")
        @lombok.Generated
        public Map<String, Object> getAttributes() {
            return this.attributes;
        }

        @java.lang.SuppressWarnings("all")
        @lombok.Generated
        public void setType(final String type) {
            this.type = type;
        }

        @java.lang.SuppressWarnings("all")
        @lombok.Generated
        public void setAttributes(final Map<String, Object> attributes) {
            this.attributes = attributes;
        }

        @java.lang.Override
        @java.lang.SuppressWarnings("all")
        @lombok.Generated
        public boolean equals(final java.lang.Object o) {
            if (o == this) {
                return true;
            }
            if (!(o instanceof TestTest.Item)) {
                return false;
            }
            final TestTest.Item other = (TestTest.Item) o;
            if (!other.canEqual(this)) {
                return false;
            }
            final java.lang.Object this$type = this.getType();
            final java.lang.Object other$type = other.getType();
            if (this$type == null ? other$type != null : !this$type.equals(other$type)) {
                return false;
            }
            final java.lang.Object this$attributes = this.getAttributes();
            final java.lang.Object other$attributes = other.getAttributes();
            if (this$attributes == null ? other$attributes != null : !this$attributes.equals(other$attributes)) {
                return false;
            }
            return true;
        }

        @java.lang.SuppressWarnings("all")
        @lombok.Generated
        protected boolean canEqual(final java.lang.Object other) {
            return other instanceof TestTest.Item;
        }

        @java.lang.Override
        @java.lang.SuppressWarnings("all")
        @lombok.Generated
        public int hashCode() {
            final int PRIME = 59;
            int result = 1;
            final java.lang.Object $type = this.getType();
            result = result * PRIME + ($type == null ? 43 : $type.hashCode());
            final java.lang.Object $attributes = this.getAttributes();
            return result * PRIME + ($attributes == null ? 43 : $attributes.hashCode());
        }

        @java.lang.Override
        @java.lang.SuppressWarnings("all")
        @lombok.Generated
        public java.lang.String toString() {
            return "TestTest.Item(type=" + this.getType() + ", attributes=" + this.getAttributes() + ")";
        }

        @java.lang.SuppressWarnings("all")
        @lombok.Generated
        public Item() {
        }

        @java.lang.SuppressWarnings("all")
        @lombok.Generated
        public Item(final String type, final Map<String, Object> attributes) {
            this.type = type;
            this.attributes = attributes;
        }
    }
}

Expected behavior

The additional properties are deserialized

Additional context

No response