diff --git a/release-notes/CREDITS-2.x b/release-notes/CREDITS-2.x index c612a32684..8961e82598 100644 --- a/release-notes/CREDITS-2.x +++ b/release-notes/CREDITS-2.x @@ -10,7 +10,6 @@ Co-Authors (with only partial listings below): * Joo Hyuk Kim (JooHyukKim@github) * PJ Fanning (pjfanning@github) -* Sim Yih Tsern (yihtsern@github) ---------------------------------------------------------------------------- @@ -1625,9 +1624,9 @@ Sim Yih Tsern (yihtsern@github) * Contributed fix for #3897: 2.15.0 breaks deserialization when POJO/Record only has a single field and is marked `Access.WRITE_ONLY` (2.15.1) - * Contributed fix fix #3968: Records with additional constructors failed to deserialize + * Contributed fux fix #3968: Records with additional constructors failed to deserialize (2.15.3) - ... and many more + Ajay Siwach (Siwach16@github) * Contributed #3637: Add enum features into `@JsonFormat.Feature` diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x index 23e1b40e3d..251ffdb7ac 100644 --- a/release-notes/VERSION-2.x +++ b/release-notes/VERSION-2.x @@ -57,12 +57,6 @@ Project: jackson-databind (reported by Eduard G) #4617: Record property serialization order not preserved (reported by @GeorgiPetkov) -#4626: `@JsonIgnore` on Record property ignored for deserialization, if there - is getter override - (contributed by @yihtserns) -#4630: `@JsonIncludeProperties`, `@JsonIgnoreProperties` ignored when serializing Records, - if there is getter override - (contributed by @yihtserns) 2.17.2 (05-Jul-2024) diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java index 53bdb1fa7d..80d9d492c2 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java @@ -977,14 +977,8 @@ protected SettableBeanProperty constructSettableProperty(DeserializationContext beanDesc.getClassAnnotations(), (AnnotatedMethod) mutator); } else { // 08-Sep-2016, tatu: wonder if we should verify it is `AnnotatedField` to be safe? - AnnotatedField field = (AnnotatedField) mutator; - // [databind#3736] Pointless to create a SettableBeanProperty for an immutable field - // Records' fields can't mutated via reflection (JDK-8247517) - // (also see [databind#4626] - if (beanDesc.isRecordType()) { - return null; - } - prop = new FieldProperty(propDef, type, typeDeser, beanDesc.getClassAnnotations(), field); + prop = new FieldProperty(propDef, type, typeDeser, + beanDesc.getClassAnnotations(), (AnnotatedField) mutator); } JsonDeserializer deser = findDeserializerFromAnnotation(ctxt, mutator); if (deser == null) { diff --git a/src/main/java/com/fasterxml/jackson/databind/introspect/POJOPropertiesCollector.java b/src/main/java/com/fasterxml/jackson/databind/introspect/POJOPropertiesCollector.java index 14481405a7..924492686a 100644 --- a/src/main/java/com/fasterxml/jackson/databind/introspect/POJOPropertiesCollector.java +++ b/src/main/java/com/fasterxml/jackson/databind/introspect/POJOPropertiesCollector.java @@ -434,7 +434,13 @@ protected void collectAll() // First: gather basic accessors LinkedHashMap props = new LinkedHashMap(); - _addFields(props); // note: populates _fieldRenameMappings + // 15-Jan-2023, tatu: [databind#3736] Let's avoid detecting fields of Records + // altogether (unless we find a good reason to detect them) + // 17-Apr-2023: Need Records' fields for serialization for cases + // like [databind#3628], [databind#3895] and [databind#3992] + if (!isRecordType() || _forSerialization) { + _addFields(props); // note: populates _fieldRenameMappings + } _addMethods(props); // 25-Jan-2016, tatu: Avoid introspecting (constructor-)creators for non-static // inner classes, see [databind#1502] @@ -1295,7 +1301,10 @@ protected void _removeUnwantedProperties(Map props) */ protected void _removeUnwantedAccessor(Map props) { - final boolean inferMutators = _config.isEnabled(MapperFeature.INFER_PROPERTY_MUTATORS); + // 15-Jan-2023, tatu: Avoid pulling in mutators for Records; Fields mostly + // since there should not be setters. + final boolean inferMutators = !isRecordType() + && _config.isEnabled(MapperFeature.INFER_PROPERTY_MUTATORS); Iterator it = props.values().iterator(); while (it.hasNext()) { diff --git a/src/test-jdk17/java/com/fasterxml/jackson/databind/records/RecordWithIgnoreOverride3992Test.java b/src/test-jdk17/java/com/fasterxml/jackson/databind/records/RecordWithIgnoreOverride3992Test.java index a1e6478241..faf005c4f2 100644 --- a/src/test-jdk17/java/com/fasterxml/jackson/databind/records/RecordWithIgnoreOverride3992Test.java +++ b/src/test-jdk17/java/com/fasterxml/jackson/databind/records/RecordWithIgnoreOverride3992Test.java @@ -50,14 +50,4 @@ public void testHelloRecord() throws Exception { HelloRecord result = MAPPER.readValue(json, HelloRecord.class); assertNotNull(result); } - - // [databind#4626] - @Test - public void testDeserialize() throws Exception { - HelloRecord expected = new HelloRecord("hello", null); - - assertEquals(expected, MAPPER.readValue(a2q("{'text':'hello'}"), HelloRecord.class)); - assertEquals(expected, MAPPER.readValue(a2q("{'text':'hello','hidden':null}"), HelloRecord.class)); - assertEquals(expected, MAPPER.readValue(a2q("{'text':'hello','hidden':{'all': []}}"), HelloRecord.class)); - } } diff --git a/src/test-jdk17/java/com/fasterxml/jackson/databind/records/RecordWithJsonIgnoreTest.java b/src/test-jdk17/java/com/fasterxml/jackson/databind/records/RecordWithJsonIgnoreTest.java index 4fb02ee485..9c372884e9 100644 --- a/src/test-jdk17/java/com/fasterxml/jackson/databind/records/RecordWithJsonIgnoreTest.java +++ b/src/test-jdk17/java/com/fasterxml/jackson/databind/records/RecordWithJsonIgnoreTest.java @@ -81,11 +81,9 @@ public void testSerializeJsonIgnoreAccessorRecord() throws Exception { @Test public void testDeserializeJsonIgnoreAccessorRecord() throws Exception { - RecordWithIgnoreAccessor expected = new RecordWithIgnoreAccessor(123, null); - - assertEquals(expected, MAPPER.readValue("{\"id\":123}", RecordWithIgnoreAccessor.class)); - assertEquals(expected, MAPPER.readValue("{\"id\":123,\"name\":null}", RecordWithIgnoreAccessor.class)); - assertEquals(expected, MAPPER.readValue("{\"id\":123,\"name\":\"Bob\"}", RecordWithIgnoreAccessor.class)); + RecordWithIgnoreAccessor value = MAPPER.readValue("{\"id\":123,\"name\":\"Bob\"}", + RecordWithIgnoreAccessor.class); + assertEquals(new RecordWithIgnoreAccessor(123, null), value); } /* diff --git a/src/test-jdk17/java/com/fasterxml/jackson/databind/records/RecordWithOverriddenAccessorTest.java b/src/test-jdk17/java/com/fasterxml/jackson/databind/records/RecordWithOverriddenAccessorTest.java deleted file mode 100644 index f0626445c1..0000000000 --- a/src/test-jdk17/java/com/fasterxml/jackson/databind/records/RecordWithOverriddenAccessorTest.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.fasterxml.jackson.databind.records; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonIncludeProperties; -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 RecordWithOverriddenAccessorTest extends DatabindTestUtil { - - record Id2Name(int id, String name) { - } - - record RecordWithJsonIncludeProperties(@JsonIncludeProperties("id") Id2Name child) { - @Override - public Id2Name child() { - return child; - } - } - - record RecordWithJsonIgnoreProperties(@JsonIgnoreProperties("name") Id2Name child) { - @Override - public Id2Name child() { - return child; - } - } - - private final ObjectMapper MAPPER = newJsonMapper(); - - // [databind#4630] - @Test - public void testSerializeJsonIncludeProperties() throws Exception { - String json = MAPPER.writeValueAsString(new RecordWithJsonIncludeProperties(new Id2Name(123, "Bob"))); - assertEquals(a2q("{'child':{'id':123}}"), json); - } - - // [databind#4630] - @Test - public void testSerializeJsonIgnoreProperties() throws Exception { - String json = MAPPER.writeValueAsString(new RecordWithJsonIgnoreProperties(new Id2Name(123, "Bob"))); - assertEquals(a2q("{'child':{'id':123}}"), json); - } -}