From ea99746983735c2d96a067e9bd23e7578ebf574d Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Sat, 13 May 2023 17:10:43 +0100 Subject: [PATCH 01/10] Create RecordSerializationOrderTest.java --- .../records/RecordSerializationOrderTest.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/test-jdk14/java/com/fasterxml/jackson/databind/records/RecordSerializationOrderTest.java diff --git a/src/test-jdk14/java/com/fasterxml/jackson/databind/records/RecordSerializationOrderTest.java b/src/test-jdk14/java/com/fasterxml/jackson/databind/records/RecordSerializationOrderTest.java new file mode 100644 index 0000000000..8f8c96902c --- /dev/null +++ b/src/test-jdk14/java/com/fasterxml/jackson/databind/records/RecordSerializationOrderTest.java @@ -0,0 +1,26 @@ +package com.fasterxml.jackson.databind.records; + +import com.fasterxml.jackson.databind.BaseMapTest; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class RecordSerializationOrderTest extends BaseMapTest +{ + record NestedRecordOne(String id, String email, NestedRecordTwo nestedRecordTwo) {} + record NestedRecordTwo(String id, String passport) {} + + private final ObjectMapper MAPPER = newJsonMapper(); + + /* + /********************************************************************** + /* Test methods, alternate constructors + /********************************************************************** + */ + + public void testSerializationOrder() throws Exception { + NestedRecordTwo nestedRecordTwo = new NestedRecordTwo("2", "111110"); + NestedRecordOne nestedRecordOne = new NestedRecordOne("1", "test@records.com", nestedRecordTwo); + final String output = MAPPER.writeValueAsString(nestedRecordOne); + final String expected = "{\"id\":\"1\",\"email\":\"test@records.com\",\"nestedRecordTwo\":{\"id\":\"2\",\"passport\":\"111110\"}}"; + assertEquals(expected, output); + } +} From f1c69c961f914ca2c2031863c5eaabe17a7481ba Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Sat, 13 May 2023 17:19:35 +0100 Subject: [PATCH 02/10] Update RecordSerializationOrderTest.java --- .../records/RecordSerializationOrderTest.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/test-jdk14/java/com/fasterxml/jackson/databind/records/RecordSerializationOrderTest.java b/src/test-jdk14/java/com/fasterxml/jackson/databind/records/RecordSerializationOrderTest.java index 8f8c96902c..afa835c239 100644 --- a/src/test-jdk14/java/com/fasterxml/jackson/databind/records/RecordSerializationOrderTest.java +++ b/src/test-jdk14/java/com/fasterxml/jackson/databind/records/RecordSerializationOrderTest.java @@ -1,11 +1,14 @@ package com.fasterxml.jackson.databind.records; +import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.BaseMapTest; import com.fasterxml.jackson.databind.ObjectMapper; public class RecordSerializationOrderTest extends BaseMapTest { record NestedRecordOne(String id, String email, NestedRecordTwo nestedRecordTwo) {} + record NestedRecordOneWithJsonProperty(String id, String email, + @JsonProperty("nestedProperty") NestedRecordTwo nestedRecordTwo) {} record NestedRecordTwo(String id, String passport) {} private final ObjectMapper MAPPER = newJsonMapper(); @@ -23,4 +26,13 @@ public void testSerializationOrder() throws Exception { final String expected = "{\"id\":\"1\",\"email\":\"test@records.com\",\"nestedRecordTwo\":{\"id\":\"2\",\"passport\":\"111110\"}}"; assertEquals(expected, output); } + + public void testSerializationOrderWithJsonProperty() throws Exception { + NestedRecordTwo nestedRecordTwo = new NestedRecordTwo("2", "111110"); + NestedRecordOneWithJsonProperty nestedRecordOne = + new NestedRecordOneWithJsonProperty("1", "test@records.com", nestedRecordTwo); + final String output = MAPPER.writeValueAsString(nestedRecordOne); + final String expected = "{\"id\":\"1\",\"email\":\"test@records.com\",\"nestedRecordTwo\":{\"id\":\"2\",\"passport\":\"111110\"}}"; + assertEquals(expected, output); + } } From 1001f257e9196d598a7325f9f3002f54a974b4f6 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Sat, 13 May 2023 18:01:43 +0100 Subject: [PATCH 03/10] try to fix test --- .../databind/introspect/POJOPropertiesCollector.java | 6 +++--- .../databind/records/RecordSerializationOrderTest.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) 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 a2893650f0..fcae82bf84 100644 --- a/src/main/java/com/fasterxml/jackson/databind/introspect/POJOPropertiesCollector.java +++ b/src/main/java/com/fasterxml/jackson/databind/introspect/POJOPropertiesCollector.java @@ -437,17 +437,17 @@ protected void collectAll() LinkedHashMap props = new LinkedHashMap(); // First: gather basic data - + final boolean isRecord = isRecordType(); // 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#3895] & [databind#3628] - if (!isRecordType() || _forSerialization) { + if (!isRecord || _forSerialization) { _addFields(props); // note: populates _fieldRenameMappings } _addMethods(props); // 25-Jan-2016, tatu: Avoid introspecting (constructor-)creators for non-static // inner classes, see [databind#1502] - if (!_classDef.isNonStaticInnerClass()) { + if (!_classDef.isNonStaticInnerClass() && !isRecord) { _addCreators(props); } diff --git a/src/test-jdk14/java/com/fasterxml/jackson/databind/records/RecordSerializationOrderTest.java b/src/test-jdk14/java/com/fasterxml/jackson/databind/records/RecordSerializationOrderTest.java index afa835c239..fb7aa831aa 100644 --- a/src/test-jdk14/java/com/fasterxml/jackson/databind/records/RecordSerializationOrderTest.java +++ b/src/test-jdk14/java/com/fasterxml/jackson/databind/records/RecordSerializationOrderTest.java @@ -32,7 +32,7 @@ public void testSerializationOrderWithJsonProperty() throws Exception { NestedRecordOneWithJsonProperty nestedRecordOne = new NestedRecordOneWithJsonProperty("1", "test@records.com", nestedRecordTwo); final String output = MAPPER.writeValueAsString(nestedRecordOne); - final String expected = "{\"id\":\"1\",\"email\":\"test@records.com\",\"nestedRecordTwo\":{\"id\":\"2\",\"passport\":\"111110\"}}"; + final String expected = "{\"id\":\"1\",\"email\":\"test@records.com\",\"nestedProperty\":{\"id\":\"2\",\"passport\":\"111110\"}}"; assertEquals(expected, output); } } From 4be5bf4f17d3943d7682f7a6978642bd735c680a Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Sat, 13 May 2023 18:09:41 +0100 Subject: [PATCH 04/10] Revert "try to fix test" This reverts commit 1001f257e9196d598a7325f9f3002f54a974b4f6. --- .../databind/introspect/POJOPropertiesCollector.java | 6 +++--- .../databind/records/RecordSerializationOrderTest.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) 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 fcae82bf84..a2893650f0 100644 --- a/src/main/java/com/fasterxml/jackson/databind/introspect/POJOPropertiesCollector.java +++ b/src/main/java/com/fasterxml/jackson/databind/introspect/POJOPropertiesCollector.java @@ -437,17 +437,17 @@ protected void collectAll() LinkedHashMap props = new LinkedHashMap(); // First: gather basic data - final boolean isRecord = isRecordType(); + // 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#3895] & [databind#3628] - if (!isRecord || _forSerialization) { + 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] - if (!_classDef.isNonStaticInnerClass() && !isRecord) { + if (!_classDef.isNonStaticInnerClass()) { _addCreators(props); } diff --git a/src/test-jdk14/java/com/fasterxml/jackson/databind/records/RecordSerializationOrderTest.java b/src/test-jdk14/java/com/fasterxml/jackson/databind/records/RecordSerializationOrderTest.java index fb7aa831aa..afa835c239 100644 --- a/src/test-jdk14/java/com/fasterxml/jackson/databind/records/RecordSerializationOrderTest.java +++ b/src/test-jdk14/java/com/fasterxml/jackson/databind/records/RecordSerializationOrderTest.java @@ -32,7 +32,7 @@ public void testSerializationOrderWithJsonProperty() throws Exception { NestedRecordOneWithJsonProperty nestedRecordOne = new NestedRecordOneWithJsonProperty("1", "test@records.com", nestedRecordTwo); final String output = MAPPER.writeValueAsString(nestedRecordOne); - final String expected = "{\"id\":\"1\",\"email\":\"test@records.com\",\"nestedProperty\":{\"id\":\"2\",\"passport\":\"111110\"}}"; + final String expected = "{\"id\":\"1\",\"email\":\"test@records.com\",\"nestedRecordTwo\":{\"id\":\"2\",\"passport\":\"111110\"}}"; assertEquals(expected, output); } } From 4e00229f961d51535fa15b29b86f51458c104a35 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Sat, 13 May 2023 18:12:43 +0100 Subject: [PATCH 05/10] Update RecordSerializationOrderTest.java --- .../jackson/databind/records/RecordSerializationOrderTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test-jdk14/java/com/fasterxml/jackson/databind/records/RecordSerializationOrderTest.java b/src/test-jdk14/java/com/fasterxml/jackson/databind/records/RecordSerializationOrderTest.java index afa835c239..fb7aa831aa 100644 --- a/src/test-jdk14/java/com/fasterxml/jackson/databind/records/RecordSerializationOrderTest.java +++ b/src/test-jdk14/java/com/fasterxml/jackson/databind/records/RecordSerializationOrderTest.java @@ -32,7 +32,7 @@ public void testSerializationOrderWithJsonProperty() throws Exception { NestedRecordOneWithJsonProperty nestedRecordOne = new NestedRecordOneWithJsonProperty("1", "test@records.com", nestedRecordTwo); final String output = MAPPER.writeValueAsString(nestedRecordOne); - final String expected = "{\"id\":\"1\",\"email\":\"test@records.com\",\"nestedRecordTwo\":{\"id\":\"2\",\"passport\":\"111110\"}}"; + final String expected = "{\"id\":\"1\",\"email\":\"test@records.com\",\"nestedProperty\":{\"id\":\"2\",\"passport\":\"111110\"}}"; assertEquals(expected, output); } } From 38023b6c73af579958b0ee3cdc5e6ef4eed9babb Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Sat, 13 May 2023 20:13:50 +0100 Subject: [PATCH 06/10] Revert "Revert "try to fix test"" This reverts commit 4be5bf4f17d3943d7682f7a6978642bd735c680a. --- .../databind/introspect/POJOPropertiesCollector.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 a2893650f0..fcae82bf84 100644 --- a/src/main/java/com/fasterxml/jackson/databind/introspect/POJOPropertiesCollector.java +++ b/src/main/java/com/fasterxml/jackson/databind/introspect/POJOPropertiesCollector.java @@ -437,17 +437,17 @@ protected void collectAll() LinkedHashMap props = new LinkedHashMap(); // First: gather basic data - + final boolean isRecord = isRecordType(); // 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#3895] & [databind#3628] - if (!isRecordType() || _forSerialization) { + if (!isRecord || _forSerialization) { _addFields(props); // note: populates _fieldRenameMappings } _addMethods(props); // 25-Jan-2016, tatu: Avoid introspecting (constructor-)creators for non-static // inner classes, see [databind#1502] - if (!_classDef.isNonStaticInnerClass()) { + if (!_classDef.isNonStaticInnerClass() && !isRecord) { _addCreators(props); } From 1bccb075556e5b04df49150688a521c5c7dd3d2c Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Sat, 13 May 2023 20:31:33 +0100 Subject: [PATCH 07/10] Update POJOPropertiesCollector.java --- .../jackson/databind/introspect/POJOPropertiesCollector.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 fcae82bf84..df3dfe0adc 100644 --- a/src/main/java/com/fasterxml/jackson/databind/introspect/POJOPropertiesCollector.java +++ b/src/main/java/com/fasterxml/jackson/databind/introspect/POJOPropertiesCollector.java @@ -447,7 +447,8 @@ protected void collectAll() _addMethods(props); // 25-Jan-2016, tatu: Avoid introspecting (constructor-)creators for non-static // inner classes, see [databind#1502] - if (!_classDef.isNonStaticInnerClass() && !isRecord) { + // 13-May-2023, PJ: Need to avoid adding creators for Records when serializing [databind#3925] + if (!_classDef.isNonStaticInnerClass() && (!_forSerialization || !isRecord)) { _addCreators(props); } From 1bd87c67cd884c99d4aee11dc2aee4c899dac93b Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Mon, 15 May 2023 10:26:21 +0100 Subject: [PATCH 08/10] Update RecordSerializationOrderTest.java --- .../records/RecordSerializationOrderTest.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/test-jdk14/java/com/fasterxml/jackson/databind/records/RecordSerializationOrderTest.java b/src/test-jdk14/java/com/fasterxml/jackson/databind/records/RecordSerializationOrderTest.java index fb7aa831aa..3aff4510d6 100644 --- a/src/test-jdk14/java/com/fasterxml/jackson/databind/records/RecordSerializationOrderTest.java +++ b/src/test-jdk14/java/com/fasterxml/jackson/databind/records/RecordSerializationOrderTest.java @@ -9,6 +9,9 @@ public class RecordSerializationOrderTest extends BaseMapTest record NestedRecordOne(String id, String email, NestedRecordTwo nestedRecordTwo) {} record NestedRecordOneWithJsonProperty(String id, String email, @JsonProperty("nestedProperty") NestedRecordTwo nestedRecordTwo) {} + record NestedRecordOneWithJsonPropertyOrder(@JsonProperty(index = 2) String id, + @JsonProperty(index = 0) String email, + @JsonProperty(value = "nestedProperty", index = 1) NestedRecordTwo nestedRecordTwo) {} record NestedRecordTwo(String id, String passport) {} private final ObjectMapper MAPPER = newJsonMapper(); @@ -35,4 +38,13 @@ public void testSerializationOrderWithJsonProperty() throws Exception { final String expected = "{\"id\":\"1\",\"email\":\"test@records.com\",\"nestedProperty\":{\"id\":\"2\",\"passport\":\"111110\"}}"; assertEquals(expected, output); } + + public void testSerializationOrderWithJsonPropertyOrder() throws Exception { + NestedRecordTwo nestedRecordTwo = new NestedRecordTwo("2", "111110"); + NestedRecordOneWithJsonPropertyOrder nestedRecordOne = + new NestedRecordOneWithJsonPropertyOrder("1", "test@records.com", nestedRecordTwo); + final String output = MAPPER.writeValueAsString(nestedRecordOne); + final String expected = "{\"email\":\"test@records.com\",\"nestedProperty\":{\"id\":\"2\",\"passport\":\"111110\"},\"id\":\"1\"}"; + assertEquals(expected, output); + } } From d01db2b312c87f7bf247730a79d0ec7013141eee Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Mon, 15 May 2023 12:04:45 +0100 Subject: [PATCH 09/10] Update src/main/java/com/fasterxml/jackson/databind/introspect/POJOPropertiesCollector.java Co-authored-by: Kim, Joo Hyuk --- .../jackson/databind/introspect/POJOPropertiesCollector.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 df3dfe0adc..40df20e693 100644 --- a/src/main/java/com/fasterxml/jackson/databind/introspect/POJOPropertiesCollector.java +++ b/src/main/java/com/fasterxml/jackson/databind/introspect/POJOPropertiesCollector.java @@ -448,7 +448,7 @@ protected void collectAll() // 25-Jan-2016, tatu: Avoid introspecting (constructor-)creators for non-static // inner classes, see [databind#1502] // 13-May-2023, PJ: Need to avoid adding creators for Records when serializing [databind#3925] - if (!_classDef.isNonStaticInnerClass() && (!_forSerialization || !isRecord)) { + if (!_classDef.isNonStaticInnerClass() && !(_forSerialization && isRecord)) { _addCreators(props); } From b59164466289d3c2e87dc4eeb1e49fe956680542 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Mon, 15 May 2023 14:13:08 +0100 Subject: [PATCH 10/10] Update RecordSerializationOrderTest.java --- .../records/RecordSerializationOrderTest.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/test-jdk14/java/com/fasterxml/jackson/databind/records/RecordSerializationOrderTest.java b/src/test-jdk14/java/com/fasterxml/jackson/databind/records/RecordSerializationOrderTest.java index 3aff4510d6..494904c3e9 100644 --- a/src/test-jdk14/java/com/fasterxml/jackson/databind/records/RecordSerializationOrderTest.java +++ b/src/test-jdk14/java/com/fasterxml/jackson/databind/records/RecordSerializationOrderTest.java @@ -1,6 +1,7 @@ package com.fasterxml.jackson.databind.records; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fasterxml.jackson.databind.BaseMapTest; import com.fasterxml.jackson.databind.ObjectMapper; @@ -9,9 +10,15 @@ public class RecordSerializationOrderTest extends BaseMapTest record NestedRecordOne(String id, String email, NestedRecordTwo nestedRecordTwo) {} record NestedRecordOneWithJsonProperty(String id, String email, @JsonProperty("nestedProperty") NestedRecordTwo nestedRecordTwo) {} - record NestedRecordOneWithJsonPropertyOrder(@JsonProperty(index = 2) String id, + record NestedRecordOneWithJsonPropertyIndex(@JsonProperty(index = 2) String id, @JsonProperty(index = 0) String email, @JsonProperty(value = "nestedProperty", index = 1) NestedRecordTwo nestedRecordTwo) {} + + @JsonPropertyOrder({"email", "nestedProperty", "id"}) + record NestedRecordOneWithJsonPropertyOrder(String id, + String email, + @JsonProperty(value = "nestedProperty") NestedRecordTwo nestedRecordTwo) {} + record NestedRecordTwo(String id, String passport) {} private final ObjectMapper MAPPER = newJsonMapper(); @@ -39,6 +46,15 @@ public void testSerializationOrderWithJsonProperty() throws Exception { assertEquals(expected, output); } + public void testSerializationOrderWithJsonPropertyIndexes() throws Exception { + NestedRecordTwo nestedRecordTwo = new NestedRecordTwo("2", "111110"); + NestedRecordOneWithJsonPropertyIndex nestedRecordOne = + new NestedRecordOneWithJsonPropertyIndex("1", "test@records.com", nestedRecordTwo); + final String output = MAPPER.writeValueAsString(nestedRecordOne); + final String expected = "{\"email\":\"test@records.com\",\"nestedProperty\":{\"id\":\"2\",\"passport\":\"111110\"},\"id\":\"1\"}"; + assertEquals(expected, output); + } + public void testSerializationOrderWithJsonPropertyOrder() throws Exception { NestedRecordTwo nestedRecordTwo = new NestedRecordTwo("2", "111110"); NestedRecordOneWithJsonPropertyOrder nestedRecordOne =