Skip to content

Commit 2193138

Browse files
authored
Fix #4724 (delegating creator, Records) (#4740)
1 parent cbf71a3 commit 2193138

File tree

5 files changed

+27
-14
lines changed

5 files changed

+27
-14
lines changed

release-notes/CREDITS-2.x

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1670,6 +1670,9 @@ Antti Lampinen (arlampin@github)
16701670
* Reported #3897: 2.15.0 breaks deserialization when POJO/Record only has a single field
16711671
and is marked `Access.WRITE_ONLY`
16721672
(2.15.1)
1673+
* Reported #4724: Deserialization behavior change with Records, `@JsonCreator` and
1674+
`@JsonValue` between 2.17 and 2.18
1675+
(2.18.1)
16731676
16741677
Dmitry Bolotin (dbolotin@github)
16751678
* Reported #1172: `@JsonView` doesn't work with `@JsonCreator`

release-notes/VERSION-2.x

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ Project: jackson-databind
1010
(reported by @MaximValeev)
1111
(fix by Joo-Hyuk K)
1212
#4718: Should not fail on trying to serialize `java.time.DateTimeException`
13+
#4724: Deserialization behavior change with Records, `@JsonCreator` and
14+
`@JsonValue` between 2.17 and 2.18
15+
(reported by Antti L)
1316

1417
2.18.0 (26-Sep-2024)
1518

src/main/java/com/fasterxml/jackson/databind/introspect/POJOPropertiesCollector.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -689,17 +689,22 @@ protected void _addCreators(Map<String, POJOPropertyBuilder> props)
689689
_addCreatorsWithAnnotatedNames(creators, constructors, defaultCreator);
690690
}
691691

692-
// But if no annotation-based Creators found, find/use Primary Creator
692+
// But if no annotation-based Creators found, find/use Default Creator
693693
// detected earlier, if any
694694
if (defaultCreator != null) {
695-
if (!creators.hasPropertiesBased()) {
696-
// ... but only process if still included as a candidate
697-
if (constructors.remove(defaultCreator)
698-
|| factories.remove(defaultCreator)) {
699-
// But wait! Could be delegating
700-
if (_isDelegatingConstructor(defaultCreator)) {
695+
// ... but only process if still included as a candidate
696+
if (constructors.remove(defaultCreator)
697+
|| factories.remove(defaultCreator)) {
698+
// and then consider delegating- vs properties-based
699+
if (_isDelegatingConstructor(defaultCreator)) {
700+
// 08-Oct-2024, tatu: [databind#4724] Only add if no explicit
701+
// candidates added
702+
if (!creators.hasDelegating()) {
703+
// ... not technically explicit but simpler this way
701704
creators.addExplicitDelegating(defaultCreator);
702-
} else {
705+
}
706+
} else { // default creator is properties-based
707+
if (!creators.hasPropertiesBased()) {
703708
creators.setPropertiesBased(_config, defaultCreator, "Primary");
704709
}
705710
}

src/main/java/com/fasterxml/jackson/databind/introspect/PotentialCreators.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ public void setImplicitDelegating(List<PotentialCreator> implicitConstructors,
5656
/**********************************************************************
5757
*/
5858

59+
// @since 2.18.1
60+
public boolean hasDelegating() {
61+
return (explicitDelegating != null) && !explicitDelegating.isEmpty();
62+
}
63+
5964
public boolean hasPropertiesBased() {
6065
return (propertiesBased != null);
6166
}

src/test-jdk17/java/com/fasterxml/jackson/databind/tofix/RecordJsonCreatorAndJsonValue4724Test.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,23 @@
11
package com.fasterxml.jackson.databind.tofix;
22

3+
import org.junit.jupiter.api.Test;
4+
35
import com.fasterxml.jackson.annotation.JsonCreator;
46
import com.fasterxml.jackson.annotation.JsonValue;
57
import com.fasterxml.jackson.databind.testutil.DatabindTestUtil;
6-
import com.fasterxml.jackson.databind.testutil.failure.JacksonTestFailureExpected;
7-
8-
import org.junit.jupiter.api.Test;
98

109
// [databind#4724] Deserialization behavior change with Java Records, JsonCreator and JsonValue between 2.17.2 => 2.18.0
1110
public class RecordJsonCreatorAndJsonValue4724Test
1211
extends DatabindTestUtil
1312
{
14-
1513
public record Something(String value) {
1614
public Something {
1715
if (value == null || value.isEmpty()) {
1816
throw new IllegalArgumentException("Value cannot be null or empty");
1917
}
2018
}
2119

20+
// should be considered Delegating due to @JsonValue later on
2221
@JsonCreator
2322
public static Something of(String value) {
2423
if (value.isEmpty()) {
@@ -34,10 +33,8 @@ public String toString() {
3433
}
3534
}
3635

37-
@JacksonTestFailureExpected
3836
@Test
3937
void deserialization() throws Exception {
4038
newJsonMapper().readValue("\"\"", Something.class);
4139
}
42-
4340
}

0 commit comments

Comments
 (0)