From 3a97f0720d78145b266fd124e368721dc59cb427 Mon Sep 17 00:00:00 2001 From: "Kim, Joo Hyuk" Date: Thu, 10 Oct 2024 20:06:37 +0900 Subject: [PATCH 1/3] fix and test Fix and test Delete GoodTest.java --- .../jackson/databind/ser/PropertyBuilder.java | 10 ++++- .../ser/filter/JsonInclude4741Test.java | 44 +++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 src/test/java/com/fasterxml/jackson/databind/ser/filter/JsonInclude4741Test.java diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/PropertyBuilder.java b/src/main/java/com/fasterxml/jackson/databind/ser/PropertyBuilder.java index 3ea096d672..e781a64b37 100644 --- a/src/main/java/com/fasterxml/jackson/databind/ser/PropertyBuilder.java +++ b/src/main/java/com/fasterxml/jackson/databind/ser/PropertyBuilder.java @@ -182,8 +182,14 @@ protected BeanPropertyWriter buildWriter(SerializerProvider prov, } if (valueToSuppress == null) { suppressNulls = true; - // [databind#4464] NON_DEFAULT does not work with NON_EMPTY for custom serializer - valueToSuppress = BeanPropertyWriter.MARKER_FOR_EMPTY; + // [databind#4471] Since 2.18.1 Different behavior when Include.NON_DEFAULT setting is used on + // POJO vs global setting, as per documentation. + boolean isGloballyConfigured = _config.getDefaultInclusion(actualType.getRawClass(), rawPropertyType) + .getValueInclusion() == JsonInclude.Include.NON_DEFAULT; + if (isGloballyConfigured) { + // [databind#4464] NON_DEFAULT does not work with NON_EMPTY for custom serializer + valueToSuppress = BeanPropertyWriter.MARKER_FOR_EMPTY; + } } else { if (valueToSuppress.getClass().isArray()) { valueToSuppress = ArrayBuilders.getArrayComparator(valueToSuppress); diff --git a/src/test/java/com/fasterxml/jackson/databind/ser/filter/JsonInclude4741Test.java b/src/test/java/com/fasterxml/jackson/databind/ser/filter/JsonInclude4741Test.java new file mode 100644 index 0000000000..4033cdb9d2 --- /dev/null +++ b/src/test/java/com/fasterxml/jackson/databind/ser/filter/JsonInclude4741Test.java @@ -0,0 +1,44 @@ +package com.fasterxml.jackson.databind.ser.filter; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.testutil.DatabindTestUtil; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class JsonInclude4741Test + extends DatabindTestUtil +{ + + private ObjectMapper MAPPER = newJsonMapper(); + + @Test + void testSerialization() throws JsonProcessingException + { + MyString input = new MyString(); + input.setValue(""); + + String json = MAPPER.writeValueAsString(input); + MyString output = MAPPER.readValue(json, MyString.class); + + assertEquals(input.getValue(), output.getValue()); + } + + @JsonInclude(JsonInclude.Include.NON_DEFAULT) + public static class MyString { + private String value = null; + + // Getter + public String getValue() { + return value; + } + + // Setter + public void setValue(String value) { + this.value = value; + } + } +} From abb659a5daff21de3d49b150be36240f5345c0f3 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Tue, 15 Oct 2024 17:24:13 -0700 Subject: [PATCH 2/3] Add release notes, simplify test a bit --- release-notes/VERSION-2.x | 4 +++ .../ser/filter/JsonInclude4741Test.java | 34 +++++++------------ 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x index 23c805744b..7cdba12a45 100644 --- a/release-notes/VERSION-2.x +++ b/release-notes/VERSION-2.x @@ -6,6 +6,10 @@ Project: jackson-databind 2.18.1 (WIP-2024) +#4741: When `Include.NON_DEFAULT` setting is used on POJO, empty values + are not included in json if default is `null` + (reported by @ragnhov) + (fix by Joo-Hyuk K) #4749: Fixed a problem with `StdDelegatingSerializer#serializeWithType` looking up the serializer with the wrong argument (fix by wrongwrong) diff --git a/src/test/java/com/fasterxml/jackson/databind/ser/filter/JsonInclude4741Test.java b/src/test/java/com/fasterxml/jackson/databind/ser/filter/JsonInclude4741Test.java index 4033cdb9d2..7dc6bcc890 100644 --- a/src/test/java/com/fasterxml/jackson/databind/ser/filter/JsonInclude4741Test.java +++ b/src/test/java/com/fasterxml/jackson/databind/ser/filter/JsonInclude4741Test.java @@ -1,44 +1,34 @@ package com.fasterxml.jackson.databind.ser.filter; +import org.junit.jupiter.api.Test; + import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.testutil.DatabindTestUtil; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertEquals; public class JsonInclude4741Test - extends DatabindTestUtil + extends DatabindTestUtil { + @JsonInclude(JsonInclude.Include.NON_DEFAULT) + public static class MyString { + public String value = null; + } private ObjectMapper MAPPER = newJsonMapper(); @Test - void testSerialization() throws JsonProcessingException + void testSerialization() throws Exception { MyString input = new MyString(); - input.setValue(""); + input.value = ""; String json = MAPPER.writeValueAsString(input); - MyString output = MAPPER.readValue(json, MyString.class); - - assertEquals(input.getValue(), output.getValue()); - } + assertEquals(a2q("{'value':''}"), json); - @JsonInclude(JsonInclude.Include.NON_DEFAULT) - public static class MyString { - private String value = null; - - // Getter - public String getValue() { - return value; - } + MyString output = MAPPER.readValue(json, MyString.class); - // Setter - public void setValue(String value) { - this.value = value; - } + assertEquals(input.value, output.value); } } From b2159ec9a87612a0d0273ff48c0ab61e43f566a6 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Tue, 15 Oct 2024 17:41:01 -0700 Subject: [PATCH 3/3] Change the proposed fix slightly --- .../fasterxml/jackson/databind/ser/PropertyBuilder.java | 8 +++----- .../jackson/databind/ser/filter/JsonInclude4741Test.java | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/PropertyBuilder.java b/src/main/java/com/fasterxml/jackson/databind/ser/PropertyBuilder.java index e781a64b37..8ba0df005f 100644 --- a/src/main/java/com/fasterxml/jackson/databind/ser/PropertyBuilder.java +++ b/src/main/java/com/fasterxml/jackson/databind/ser/PropertyBuilder.java @@ -182,11 +182,9 @@ protected BeanPropertyWriter buildWriter(SerializerProvider prov, } if (valueToSuppress == null) { suppressNulls = true; - // [databind#4471] Since 2.18.1 Different behavior when Include.NON_DEFAULT setting is used on - // POJO vs global setting, as per documentation. - boolean isGloballyConfigured = _config.getDefaultInclusion(actualType.getRawClass(), rawPropertyType) - .getValueInclusion() == JsonInclude.Include.NON_DEFAULT; - if (isGloballyConfigured) { + // [databind#4471] Different behavior when Include.NON_DEFAULT + // setting is used on POJO vs global setting, as per documentation. + if (!_useRealPropertyDefaults) { // [databind#4464] NON_DEFAULT does not work with NON_EMPTY for custom serializer valueToSuppress = BeanPropertyWriter.MARKER_FOR_EMPTY; } diff --git a/src/test/java/com/fasterxml/jackson/databind/ser/filter/JsonInclude4741Test.java b/src/test/java/com/fasterxml/jackson/databind/ser/filter/JsonInclude4741Test.java index 7dc6bcc890..8cb572531a 100644 --- a/src/test/java/com/fasterxml/jackson/databind/ser/filter/JsonInclude4741Test.java +++ b/src/test/java/com/fasterxml/jackson/databind/ser/filter/JsonInclude4741Test.java @@ -16,7 +16,7 @@ public static class MyString { public String value = null; } - private ObjectMapper MAPPER = newJsonMapper(); + private final ObjectMapper MAPPER = newJsonMapper(); @Test void testSerialization() throws Exception