Skip to content

Commit 24c1e30

Browse files
authored
Ignore ConstructorDetector.SingleArgConstructor.PROPERTIES preference for Records. (#3969)
1 parent a1e6208 commit 24c1e30

File tree

2 files changed

+78
-1
lines changed

2 files changed

+78
-1
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,9 @@ protected void _addImplicitConstructorCreators(DeserializationContext ctxt,
482482
final AnnotationIntrospector intr = ccState.annotationIntrospector();
483483
final VisibilityChecker<?> vchecker = ccState.vchecker;
484484
List<AnnotatedWithParams> implicitCtors = null;
485-
final boolean preferPropsBased = config.getConstructorDetector().singleArgCreatorDefaultsToProperties();
485+
final boolean preferPropsBased = config.getConstructorDetector().singleArgCreatorDefaultsToProperties()
486+
// [databind#3968]: Only Record's canonical constructor is allowed to be considered for properties-based creator
487+
&& !beanDesc.isRecordType();
486488

487489
for (CreatorCandidate candidate : ctorCandidates) {
488490
final int argCount = candidate.paramCount();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package com.fasterxml.jackson.databind.records;
2+
3+
import com.fasterxml.jackson.databind.BaseMapTest;
4+
import com.fasterxml.jackson.databind.ObjectMapper;
5+
import com.fasterxml.jackson.databind.cfg.ConstructorDetector;
6+
import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException;
7+
8+
public class RecordImplicitSingleValueUsePropertiesBasedCreatorsTest extends BaseMapTest
9+
{
10+
11+
record RecordWithMultiValueCanonAndSingleValueAltConstructor(int id, String name) {
12+
13+
public RecordWithMultiValueCanonAndSingleValueAltConstructor(int id) {
14+
this(id, "AltConstructor");
15+
}
16+
}
17+
18+
record RecordWithSingleValueCanonAndMultiValueAltConstructor(String name) {
19+
20+
public RecordWithSingleValueCanonAndMultiValueAltConstructor(String name, String email) {
21+
this("AltConstructor");
22+
}
23+
}
24+
25+
private final ObjectMapper MAPPER = jsonMapperBuilder()
26+
.annotationIntrospector(new Jdk8ConstructorParameterNameAnnotationIntrospector())
27+
.constructorDetector(ConstructorDetector.USE_PROPERTIES_BASED)
28+
.build();
29+
30+
/*
31+
/**********************************************************************
32+
/* Test methods, multi-value canonical constructor + single-value alt constructor
33+
/**********************************************************************
34+
*/
35+
36+
public void testDeserializeMultipleConstructors_UsingMultiValueCanonicalConstructor() throws Exception {
37+
RecordWithMultiValueCanonAndSingleValueAltConstructor value = MAPPER.readValue(
38+
a2q("{'id':123,'name':'Bob'}"),
39+
RecordWithMultiValueCanonAndSingleValueAltConstructor.class);
40+
41+
assertEquals(new RecordWithMultiValueCanonAndSingleValueAltConstructor(123, "Bob"), value);
42+
}
43+
44+
public void testDeserializeMultipleConstructors_WillIgnoreSingleValueAltConstructor() throws Exception {
45+
RecordWithMultiValueCanonAndSingleValueAltConstructor value = MAPPER.readValue(
46+
a2q("{'id':123}"),
47+
RecordWithMultiValueCanonAndSingleValueAltConstructor.class);
48+
49+
assertEquals(new RecordWithMultiValueCanonAndSingleValueAltConstructor(123, null), value);
50+
}
51+
52+
/*
53+
/**********************************************************************
54+
/* Test methods, single-value canonical constructor + multi-value alt constructor
55+
/**********************************************************************
56+
*/
57+
58+
public void testDeserializeMultipleConstructors_UsingSingleValueCanonicalConstructor() throws Exception {
59+
RecordWithSingleValueCanonAndMultiValueAltConstructor value = MAPPER.readValue(
60+
a2q("{'name':'Bob'}"),
61+
RecordWithSingleValueCanonAndMultiValueAltConstructor.class);
62+
63+
assertEquals(new RecordWithSingleValueCanonAndMultiValueAltConstructor("Bob"), value);
64+
}
65+
66+
public void testDeserializeMultipleConstructors_WillIgnoreMultiValueAltConstructor() throws Exception {
67+
try {
68+
MAPPER.readValue(a2q("{'name':'Bob','email':'[email protected]'}"), RecordWithSingleValueCanonAndMultiValueAltConstructor.class);
69+
} catch (UnrecognizedPropertyException e) {
70+
verifyException(e, "Unrecognized");
71+
verifyException(e, "\"email\"");
72+
verifyException(e, "RecordWithSingleValueCanonAndMultiValueAltConstructor");
73+
}
74+
}
75+
}

0 commit comments

Comments
 (0)