Skip to content

Commit 04a6719

Browse files
authored
Fix #4688 2.18.0-rc1 Regression deserializing with no-arg delegating JsonCreator (#4689)
1 parent 5e0d5f6 commit 04a6719

File tree

4 files changed

+89
-0
lines changed

4 files changed

+89
-0
lines changed

release-notes/CREDITS-2.x

+2
Original file line numberDiff line numberDiff line change
@@ -849,6 +849,8 @@ Carter Kozak (carterkozak@github)
849849
* Contributed #3876: `TypeFactory` cache performance degradation with
850850
`constructSpecializedType()`
851851
(2.15.0)
852+
* Contributed #4688: Should allow deserializing with no-arg `@JsonCreator(mode = DELEGATING)`
853+
(2.18.0)
852854

853855
Reinhard Prechtl (dnno@github)
854856
* Reported #2034: Serialization problem with type specialization of nested generic types

release-notes/VERSION-2.x

+2
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ Project: jackson-databind
7070
(contributed by Sim Y-T)
7171
#4678: Java records don't serialize with `MapperFeature.REQUIRE_SETTERS_FOR_GETTERS`
7272
(reported by Mathijs V)
73+
#4688: Should allow deserializing with no-arg `@JsonCreator(mode = DELEGATING)`
74+
(contributed by Carter K)
7375
7476
2.17.2 (05-Jul-2024)
7577

src/main/java/com/fasterxml/jackson/databind/deser/BasicDeserializerFactory.java

+7
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,13 @@ private boolean _addExplicitDelegatingCreator(DeserializationContext ctxt,
468468
int ix = -1;
469469
final int argCount = candidate.paramCount();
470470
SettableBeanProperty[] properties = new SettableBeanProperty[argCount];
471+
// [databind#4688]: Should still accept 0-arg (explicitly delegated) creator
472+
// for backwards-compatibility (worked in 2.17 and before)
473+
if (argCount == 0) {
474+
// "Convert" to property-based since that works well
475+
creators.addPropertyCreator(candidate.creator(), true, properties);
476+
return true;
477+
}
471478
for (int i = 0; i < argCount; ++i) {
472479
AnnotatedParameter param = candidate.parameter(i);
473480
JacksonInject.Value injectId = candidate.injection(i);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package com.fasterxml.jackson.databind.deser.creators;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import com.fasterxml.jackson.annotation.JsonCreator;
6+
import com.fasterxml.jackson.databind.ObjectMapper;
7+
import com.fasterxml.jackson.databind.testutil.DatabindTestUtil;
8+
9+
import static org.junit.jupiter.api.Assertions.assertSame;
10+
11+
// [databind#4688]
12+
public class SingletonDelegatingCreatorTest extends DatabindTestUtil
13+
{
14+
static final class NoFieldSingletonWithDelegatingCreator {
15+
static final NoFieldSingletonWithDelegatingCreator INSTANCE = new NoFieldSingletonWithDelegatingCreator();
16+
17+
private NoFieldSingletonWithDelegatingCreator() {}
18+
19+
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
20+
static NoFieldSingletonWithDelegatingCreator of() {
21+
return INSTANCE;
22+
}
23+
}
24+
25+
static final class NoFieldSingletonWithPropertiesCreator {
26+
static final NoFieldSingletonWithPropertiesCreator INSTANCE = new NoFieldSingletonWithPropertiesCreator();
27+
28+
private NoFieldSingletonWithPropertiesCreator() {}
29+
30+
@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
31+
static NoFieldSingletonWithPropertiesCreator of() {
32+
return INSTANCE;
33+
}
34+
}
35+
36+
static final class NoFieldSingletonWithDefaultCreator {
37+
static final NoFieldSingletonWithDefaultCreator INSTANCE = new NoFieldSingletonWithDefaultCreator();
38+
39+
private NoFieldSingletonWithDefaultCreator() {}
40+
41+
@JsonCreator
42+
static NoFieldSingletonWithDefaultCreator of() {
43+
return INSTANCE;
44+
}
45+
}
46+
47+
/*
48+
/**********************************************************************
49+
/* Test methods
50+
/**********************************************************************
51+
*/
52+
53+
private final ObjectMapper MAPPER = newJsonMapper();
54+
55+
@Test
56+
public void testNoFieldSingletonWithDelegatingCreator() throws Exception
57+
{
58+
NoFieldSingletonWithDelegatingCreator deserialized = MAPPER.readValue("{}",
59+
NoFieldSingletonWithDelegatingCreator.class);
60+
assertSame(NoFieldSingletonWithDelegatingCreator.INSTANCE, deserialized);
61+
}
62+
63+
@Test
64+
public void testNoFieldSingletonWithPropertiesCreator() throws Exception
65+
{
66+
NoFieldSingletonWithPropertiesCreator deserialized = MAPPER.readValue("{}",
67+
NoFieldSingletonWithPropertiesCreator.class);
68+
assertSame(NoFieldSingletonWithPropertiesCreator.INSTANCE, deserialized);
69+
}
70+
71+
@Test
72+
public void testNoFieldSingletonWithDefaultCreator() throws Exception
73+
{
74+
NoFieldSingletonWithDefaultCreator deserialized = MAPPER.readValue("{}",
75+
NoFieldSingletonWithDefaultCreator.class);
76+
assertSame(NoFieldSingletonWithDefaultCreator.INSTANCE, deserialized);
77+
}
78+
}

0 commit comments

Comments
 (0)