Skip to content

Commit 15075c6

Browse files
authored
(WIP) Fix #4589: remove MapperFeature.SORT_CREATOR_PROPERTIES_BY_DECLARATION_ORDER, change default sorting logic (#4590)
1 parent a20921d commit 15075c6

File tree

7 files changed

+23
-67
lines changed

7 files changed

+23
-67
lines changed

src/main/java/tools/jackson/databind/MapperFeature.java

-17
Original file line numberDiff line numberDiff line change
@@ -302,23 +302,6 @@ public enum MapperFeature
302302
*/
303303
SORT_CREATOR_PROPERTIES_FIRST(true),
304304

305-
/**
306-
* Feature that defines whether Creator properties (ones passed through
307-
* constructor or static factory method) should be sorted in their declaration
308-
* order if {@link #SORT_CREATOR_PROPERTIES_FIRST} is also enabled.
309-
* This is usually used to prevent alphabetic sorting for
310-
* Creator properties even if {@link #SORT_PROPERTIES_ALPHABETICALLY} is
311-
* enabled for other types of properties.
312-
*<p>
313-
* NOTE: if {@link #SORT_CREATOR_PROPERTIES_FIRST} is disabled, this feature
314-
* has no effect.
315-
*<p>
316-
* Feature is disabled by default (for backwards compatibility)
317-
*
318-
* @since 2.18
319-
*/
320-
SORT_CREATOR_PROPERTIES_BY_DECLARATION_ORDER(false),
321-
322305
/*
323306
/**********************************************************************
324307
/* Name-related features

src/main/java/tools/jackson/databind/introspect/POJOPropertiesCollector.java

+3-18
Original file line numberDiff line numberDiff line change
@@ -1530,24 +1530,9 @@ protected void _sortProperties(Map<String, POJOPropertyBuilder> props)
15301530
* order. Related question of creator vs non-creator is punted for now,
15311531
* so creator properties still fully predate non-creator ones.
15321532
*/
1533-
Collection<POJOPropertyBuilder> cr;
1534-
// 18-Jun-2024, tatu: [databind#4580] We may want to retain declaration
1535-
// order regardless
1536-
boolean sortCreatorPropsByAlpha = sortAlpha
1537-
&& !_config.isEnabled(MapperFeature.SORT_CREATOR_PROPERTIES_BY_DECLARATION_ORDER);
1538-
if (sortCreatorPropsByAlpha) {
1539-
TreeMap<String, POJOPropertyBuilder> sorted =
1540-
new TreeMap<String,POJOPropertyBuilder>();
1541-
for (POJOPropertyBuilder prop : _creatorProperties) {
1542-
if (prop != null) {
1543-
sorted.put(prop.getName(), prop);
1544-
}
1545-
}
1546-
cr = sorted.values();
1547-
} else {
1548-
cr = _creatorProperties;
1549-
}
1550-
for (POJOPropertyBuilder prop : cr) {
1533+
// 18-Jun-2024, tatu: Except in Jackson 3.0, we do NOT sort creator properties
1534+
// alphabetically if they are to be sorted before other properties.
1535+
for (POJOPropertyBuilder prop : _creatorProperties) {
15511536
if (prop == null) {
15521537
continue;
15531538
}

src/test-jdk17/java/tools/jackson/databind/records/RecordCreatorSerialization4452Test.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@
99

1010
import tools.jackson.databind.ObjectMapper;
1111
import tools.jackson.databind.json.JsonMapper;
12+
import tools.jackson.databind.testutil.DatabindTestUtil;
1213

1314
import static org.junit.jupiter.api.Assertions.assertEquals;
1415

1516
// [databind#4452] : JsonProperty not serializing field names properly on JsonCreator in record #4452
16-
class RecordCreatorSerialization4452Test {
17-
17+
class RecordCreatorSerialization4452Test extends DatabindTestUtil
18+
{
1819
public record PlainTestObject(
1920
@JsonProperty("strField") String testFieldName,
2021
@JsonProperty("intField") Integer testOtherField
@@ -43,7 +44,7 @@ public CreatorTestObject(
4344
public void testPlain() throws Exception
4445
{
4546
String result = OBJECT_MAPPER.writeValueAsString(new PlainTestObject("test", 1));
46-
assertEquals("{\"intField\":1,\"strField\":\"test\"}", result);
47+
assertEquals(a2q("{'strField':'test','intField':1}"), result);
4748
}
4849

4950
@Test

src/test-jdk17/java/tools/jackson/databind/records/RecordExplicitCreatorsTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ public void testDeserializeUsingCanonicalConstructor_WhenJsonPropertyConstructor
153153
} catch (DatabindException e) {
154154
verifyException(e, "Unrecognized property \"id\"");
155155
verifyException(e, "RecordWithTwoJsonPropertyWithoutJsonCreator");
156-
verifyException(e, "2 known properties: \"the_email\", \"the_id\"");
156+
verifyException(e, "2 known properties: \"the_id\", \"the_email\"");
157157
}
158158
}
159159

src/test-jdk17/java/tools/jackson/databind/records/RecordSerializationOrderTest.java

+7-14
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public void testSerializationOrder() throws Exception {
4242
NestedRecordTwo nestedRecordTwo = new NestedRecordTwo("2", "111110");
4343
NestedRecordOne nestedRecordOne = new NestedRecordOne("1", "[email protected]", nestedRecordTwo);
4444
final String output = MAPPER.writeValueAsString(nestedRecordOne);
45-
final String expected = "{\"email\":\"[email protected]\",\"id\":\"1\",\"nestedRecordTwo\":{\"id\":\"2\",\"passport\":\"111110\"}}";
45+
final String expected = a2q("{'id':'1','email':'[email protected]','nestedRecordTwo':{'id':'2','passport':'111110'}}");
4646
assertEquals(expected, output);
4747
}
4848

@@ -52,7 +52,7 @@ public void testSerializationOrderWithJsonProperty() throws Exception {
5252
NestedRecordOneWithJsonProperty nestedRecordOne =
5353
new NestedRecordOneWithJsonProperty("1", "[email protected]", nestedRecordTwo);
5454
final String output = MAPPER.writeValueAsString(nestedRecordOne);
55-
final String expected = "{\"email\":\"[email protected]\",\"id\":\"1\",\"nestedProperty\":{\"id\":\"2\",\"passport\":\"111110\"}}";
55+
final String expected = a2q("{'id':'1','email':'[email protected]','nestedProperty':{'id':'2','passport':'111110'}}");
5656
assertEquals(expected, output);
5757
}
5858

@@ -79,21 +79,14 @@ public void testSerializationOrderWithJsonPropertyOrder() throws Exception {
7979
// [databind#4580]
8080
@Test
8181
public void testSerializationOrderWrtCreatorAlphabetic() throws Exception {
82-
// In 3.0, sorting by Alphabetic enabled by default so
83-
assertEquals(a2q("{'a':'a','b':'b','c':'c'}"),
84-
MAPPER.writeValueAsString(new CABRecord("c", "a", "b")));
85-
// But can disable
82+
// In 3.0, sorting by Alphabetic enabled by default BUT it won't affect Creator props
8683
assertEquals(a2q("{'c':'c','a':'a','b':'b'}"),
84+
MAPPER.writeValueAsString(new CABRecord("c", "a", "b")));
85+
// Unless we disable Creator-props-first setting:
86+
assertEquals(a2q("{'a':'a','b':'b','c':'c'}"),
8787
jsonMapperBuilder()
88-
.disable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY)
88+
.disable(MapperFeature.SORT_CREATOR_PROPERTIES_FIRST)
8989
.build()
9090
.writeValueAsString(new CABRecord("c", "a", "b")));
91-
// Except if we tell it not to:
92-
assertEquals(a2q("{'c':'c','a':'a','b':'b'}"),
93-
jsonMapperBuilder()
94-
.enable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY)
95-
.enable(MapperFeature.SORT_CREATOR_PROPERTIES_BY_DECLARATION_ORDER)
96-
.build()
97-
.writeValueAsString(new CABRecord("c", "a", "b")));
9891
}
9992
}

src/test-jdk17/java/tools/jackson/databind/records/RecordWithView4085Test.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public record Record4085(int total, @JsonView(View4085Field.class) int current)
2222
public void testRecordWithView4085() throws Exception
2323
{
2424
final Record4085 input = new Record4085(1, 2);
25-
final String EXP = a2q("{'current':2,'total':1}");
25+
final String EXP = a2q("{'total':1,'current':2}");
2626
final ObjectWriter w = newJsonMapper().writer();
2727

2828
// by default, all properties included, without view

src/test/java/tools/jackson/databind/ser/SerializationOrderTest.java

+7-13
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ static class BeanWithCreator
2222
public int b;
2323
public int c;
2424

25-
@JsonCreator public BeanWithCreator(@JsonProperty("c") int c, @JsonProperty("a") int a) {
25+
@JsonCreator
26+
public BeanWithCreator(@JsonProperty("c") int c, @JsonProperty("a") int a) {
2627
this.a = a;
2728
this.c = c;
2829
}
@@ -150,7 +151,7 @@ public BeanForStrictOrdering(@JsonProperty("c") int c, @JsonProperty("a") int a)
150151

151152
@Test
152153
public void testImplicitOrderByCreator() throws Exception {
153-
assertEquals("{\"a\":2,\"c\":1,\"b\":0}",
154+
assertEquals("{\"c\":1,\"a\":2,\"b\":0}",
154155
MAPPER.writeValueAsString(new BeanWithCreator(1, 2)));
155156
}
156157

@@ -205,19 +206,12 @@ public void testCreatorVsExplicitOrdering() throws Exception
205206
@Test
206207
public void testAlphaAndCreatorOrdering() throws Exception
207208
{
208-
assertEquals(a2q("{'a':1,'b':2}"),
209+
assertEquals(a2q("{'b':2,'a':1}"),
209210
ALPHA_MAPPER.writeValueAsString(new BeanForGH311(2, 1)));
210-
}
211-
212-
// [databind#4580]
213-
@Test
214-
public void testAlphaAndCreatorDeclarationOrdering() throws Exception
215-
{
216211
final ObjectMapper mapper = jsonMapperBuilder()
217-
.enable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY)
218-
.enable(MapperFeature.SORT_CREATOR_PROPERTIES_BY_DECLARATION_ORDER)
212+
.disable(MapperFeature.SORT_CREATOR_PROPERTIES_FIRST)
219213
.build();
220-
assertEquals(a2q("{'b':2,'a':1}"),
214+
assertEquals(a2q("{'a':1,'b':2}"),
221215
mapper.writeValueAsString(new BeanForGH311(2, 1)));
222216
}
223217

@@ -240,7 +234,7 @@ public void testStrictAlphaAndCreatorOrdering() throws Exception
240234
// BUT are sorted within their own category
241235
assertTrue(ALPHA_MAPPER.isEnabled(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY));
242236
assertTrue(ALPHA_MAPPER.isEnabled(MapperFeature.SORT_CREATOR_PROPERTIES_FIRST));
243-
assertEquals(a2q("{'a':3,'c':2,'b':0}"),
237+
assertEquals(a2q("{'c':2,'a':3,'b':0}"),
244238
ALPHA_MAPPER.writeValueAsString(new BeanForStrictOrdering(2, 3)));
245239

246240
// but can change that

0 commit comments

Comments
 (0)