From 556a5bbc9805ac198833536b83f96438d52046c7 Mon Sep 17 00:00:00 2001 From: "Kim, Joo Hyuk" Date: Wed, 29 Nov 2023 07:26:01 +0900 Subject: [PATCH 1/2] Add now-passing test for #3133 (#4231) --- .../jackson/databind/BaseMapTest.java | 2 +- .../BigDecimalForFloatDisabled3133Test.java | 63 +++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 src/test/java/com/fasterxml/jackson/databind/deser/jdk/BigDecimalForFloatDisabled3133Test.java diff --git a/src/test/java/com/fasterxml/jackson/databind/BaseMapTest.java b/src/test/java/com/fasterxml/jackson/databind/BaseMapTest.java index cdb04570b6..98490b2a63 100644 --- a/src/test/java/com/fasterxml/jackson/databind/BaseMapTest.java +++ b/src/test/java/com/fasterxml/jackson/databind/BaseMapTest.java @@ -244,7 +244,7 @@ public static ObjectMapper newJsonMapper() { } // @since 2.10 - protected static JsonMapper.Builder jsonMapperBuilder() { + public static JsonMapper.Builder jsonMapperBuilder() { return JsonMapper.builder(); } diff --git a/src/test/java/com/fasterxml/jackson/databind/deser/jdk/BigDecimalForFloatDisabled3133Test.java b/src/test/java/com/fasterxml/jackson/databind/deser/jdk/BigDecimalForFloatDisabled3133Test.java new file mode 100644 index 0000000000..66be09685c --- /dev/null +++ b/src/test/java/com/fasterxml/jackson/databind/deser/jdk/BigDecimalForFloatDisabled3133Test.java @@ -0,0 +1,63 @@ +package com.fasterxml.jackson.databind.deser.jdk; + +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; + +import static com.fasterxml.jackson.databind.BaseMapTest.jsonMapperBuilder; +import static com.fasterxml.jackson.databind.BaseTest.a2q; + +/** + * 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 = TestMapContainer.class, name = "MAP"), + }) + interface TestJsonTypeInfoInterface { } + + static class TestMapContainer implements TestJsonTypeInfoInterface { + + 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(); + + @Test + public void testDeserializeWithDifferentOrdering() throws Exception { + // case 1 : type first + String ordering1 = a2q("{'type': 'MAP','map': { 'doubleValue': 0.1 }}"); + TestMapContainer model1 = mapper.readValue(ordering1, TestMapContainer.class); + Assertions.assertTrue(model1.getMap().get("doubleValue") instanceof Double); + + // case 2 : value first + String ordering2 = a2q("{'map': { 'doubleValue': 0.1 }, 'type': 'MAP'}"); + TestMapContainer model2 = mapper.readValue(ordering2, TestMapContainer.class); + Assertions.assertTrue(model2.getMap().get("doubleValue") instanceof Double); + } +} From 56356fe15bec52f18f0c05b59aa0aafa9ee8e8bf Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Tue, 28 Nov 2023 14:30:52 -0800 Subject: [PATCH 2/2] Update release notes wrt #3133 fix --- release-notes/VERSION-2.x | 3 +++ .../BigDecimalForFloatDisabled3133Test.java | 22 ++++++++++--------- 2 files changed, 15 insertions(+), 10 deletions(-) rename src/test/java/com/fasterxml/jackson/databind/{deser => jsontype}/jdk/BigDecimalForFloatDisabled3133Test.java (77%) diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x index e01cc403c5..519b8ea9c2 100644 --- a/release-notes/VERSION-2.x +++ b/release-notes/VERSION-2.x @@ -8,6 +8,9 @@ Not yet released #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/deser/jdk/BigDecimalForFloatDisabled3133Test.java b/src/test/java/com/fasterxml/jackson/databind/jsontype/jdk/BigDecimalForFloatDisabled3133Test.java similarity index 77% rename from src/test/java/com/fasterxml/jackson/databind/deser/jdk/BigDecimalForFloatDisabled3133Test.java rename to src/test/java/com/fasterxml/jackson/databind/jsontype/jdk/BigDecimalForFloatDisabled3133Test.java index 66be09685c..f0d2130d6b 100644 --- a/src/test/java/com/fasterxml/jackson/databind/deser/jdk/BigDecimalForFloatDisabled3133Test.java +++ b/src/test/java/com/fasterxml/jackson/databind/jsontype/jdk/BigDecimalForFloatDisabled3133Test.java @@ -1,4 +1,7 @@ -package com.fasterxml.jackson.databind.deser.jdk; +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; @@ -10,9 +13,6 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import static com.fasterxml.jackson.databind.BaseMapTest.jsonMapperBuilder; -import static com.fasterxml.jackson.databind.BaseTest.a2q; - /** * Unit test proving that below issue is fixed. *

@@ -27,11 +27,11 @@ public class BigDecimalForFloatDisabled3133Test property = "type") @JsonSubTypes({ - @JsonSubTypes.Type(value = TestMapContainer.class, name = "MAP"), + @JsonSubTypes.Type(value = TestMapContainer3133.class, name = "MAP"), }) - interface TestJsonTypeInfoInterface { } + interface BaseType3133 { } - static class TestMapContainer implements TestJsonTypeInfoInterface { + static class TestMapContainer3133 implements BaseType3133 { private Map map = new HashMap<>(); @@ -48,16 +48,18 @@ public void setMap(Map map) { .disable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS) .build(); + // [databind#3133] @Test - public void testDeserializeWithDifferentOrdering() throws Exception { + public void testDeserializeWithDifferentOrdering3133() throws Exception + { // case 1 : type first String ordering1 = a2q("{'type': 'MAP','map': { 'doubleValue': 0.1 }}"); - TestMapContainer model1 = mapper.readValue(ordering1, TestMapContainer.class); + 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'}"); - TestMapContainer model2 = mapper.readValue(ordering2, TestMapContainer.class); + TestMapContainer3133 model2 = mapper.readValue(ordering2, TestMapContainer3133.class); Assertions.assertTrue(model2.getMap().get("doubleValue") instanceof Double); } }