diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x index f377855960..1d186d69e8 100644 --- a/release-notes/VERSION-2.x +++ b/release-notes/VERSION-2.x @@ -119,6 +119,9 @@ Project: jackson-databind #1172: `@JsonView` doesn't work with `@JsonCreator` (reported by Dmitry B) +#3133: Map deserialization results in different numeric classes based on + json ordering (BigDecimal / Double) when used in combination with @JsonSubTypes + (reported by @mreiterer) #4185: `@JsonIgnoreProperties` with `@JsonTypeInfo(include = JsonTypeInfo.As.EXTERNAL_PROPERTY)` does not work (reported by @jonasho) diff --git a/src/test/java/com/fasterxml/jackson/databind/jsontype/jdk/BigDecimalForFloatDisabled3133Test.java b/src/test/java/com/fasterxml/jackson/databind/jsontype/jdk/BigDecimalForFloatDisabled3133Test.java new file mode 100644 index 0000000000..f0d2130d6b --- /dev/null +++ b/src/test/java/com/fasterxml/jackson/databind/jsontype/jdk/BigDecimalForFloatDisabled3133Test.java @@ -0,0 +1,65 @@ +package com.fasterxml.jackson.databind.jsontype.jdk; + +import static com.fasterxml.jackson.databind.BaseMapTest.jsonMapperBuilder; +import static com.fasterxml.jackson.databind.BaseTest.a2q; + +import java.util.HashMap; +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * Unit test proving that below issue is fixed. + *

+ * [databind#3133] Map deserialization results in different numeric classes based on json + * ordering (BigDecimal / Double) when used in combination with @JsonSubTypes + */ +public class BigDecimalForFloatDisabled3133Test +{ + @JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "type") + + @JsonSubTypes({ + @JsonSubTypes.Type(value = TestMapContainer3133.class, name = "MAP"), + }) + interface BaseType3133 { } + + static class TestMapContainer3133 implements BaseType3133 { + + private Map map = new HashMap<>(); + + public Map getMap() { + return map; + } + + public void setMap(Map map) { + this.map = map; + } + } + + private final ObjectMapper mapper = jsonMapperBuilder() + .disable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS) + .build(); + + // [databind#3133] + @Test + public void testDeserializeWithDifferentOrdering3133() throws Exception + { + // case 1 : type first + String ordering1 = a2q("{'type': 'MAP','map': { 'doubleValue': 0.1 }}"); + TestMapContainer3133 model1 = mapper.readValue(ordering1, TestMapContainer3133.class); + Assertions.assertTrue(model1.getMap().get("doubleValue") instanceof Double); + + // case 2 : value first + String ordering2 = a2q("{'map': { 'doubleValue': 0.1 }, 'type': 'MAP'}"); + TestMapContainer3133 model2 = mapper.readValue(ordering2, TestMapContainer3133.class); + Assertions.assertTrue(model2.getMap().get("doubleValue") instanceof Double); + } +}