Skip to content

Commit d44600d

Browse files
committed
Fix #1476
1 parent 002a9a3 commit d44600d

File tree

3 files changed

+75
-24
lines changed

3 files changed

+75
-24
lines changed

release-notes/VERSION

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ Project: jackson-databind
1818
#1456: `TypeFactory` type resolution broken in 2.7 for generic types
1919
when using `constructType` with context
2020
(reported by Dmitry S)
21+
#1476: Wrong constructor picked up when deserializing object
22+
(reported by laurentgo@github)
2123

2224
2.7.8 (26-Sep-2016)
2325

src/main/java/com/fasterxml/jackson/databind/deser/impl/CreatorCollector.java

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -162,36 +162,39 @@ public void addDelegatingCreator(AnnotatedWithParams creator, boolean explicit,
162162
SettableBeanProperty[] injectables)
163163
{
164164
if (creator.getParameterType(0).isCollectionLikeType()) {
165-
verifyNonDup(creator, C_ARRAY_DELEGATE, explicit);
166-
_arrayDelegateArgs = injectables;
165+
if (verifyNonDup(creator, C_ARRAY_DELEGATE, explicit)) {
166+
_arrayDelegateArgs = injectables;
167+
}
167168
} else {
168-
verifyNonDup(creator, C_DELEGATE, explicit);
169-
_delegateArgs = injectables;
169+
if (verifyNonDup(creator, C_DELEGATE, explicit)) {
170+
_delegateArgs = injectables;
171+
}
170172
}
171173
}
172174

173175
public void addPropertyCreator(AnnotatedWithParams creator, boolean explicit,
174176
SettableBeanProperty[] properties)
175177
{
176-
verifyNonDup(creator, C_PROPS, explicit);
177-
// Better ensure we have no duplicate names either...
178-
if (properties.length > 1) {
179-
HashMap<String,Integer> names = new HashMap<String,Integer>();
180-
for (int i = 0, len = properties.length; i < len; ++i) {
181-
String name = properties[i].getName();
182-
/* [Issue-13]: Need to consider Injectables, which may not have
183-
* a name at all, and need to be skipped
184-
*/
185-
if (name.length() == 0 && properties[i].getInjectableValueId() != null) {
186-
continue;
187-
}
188-
Integer old = names.put(name, Integer.valueOf(i));
189-
if (old != null) {
190-
throw new IllegalArgumentException("Duplicate creator property \""+name+"\" (index "+old+" vs "+i+")");
178+
if (verifyNonDup(creator, C_PROPS, explicit)) {
179+
// Better ensure we have no duplicate names either...
180+
if (properties.length > 1) {
181+
HashMap<String,Integer> names = new HashMap<String,Integer>();
182+
for (int i = 0, len = properties.length; i < len; ++i) {
183+
String name = properties[i].getName();
184+
/* [Issue-13]: Need to consider Injectables, which may not have
185+
* a name at all, and need to be skipped
186+
*/
187+
if (name.length() == 0 && properties[i].getInjectableValueId() != null) {
188+
continue;
189+
}
190+
Integer old = names.put(name, Integer.valueOf(i));
191+
if (old != null) {
192+
throw new IllegalArgumentException("Duplicate creator property \""+name+"\" (index "+old+" vs "+i+")");
193+
}
191194
}
192195
}
196+
_propertyBasedArgs = properties;
193197
}
194-
_propertyBasedArgs = properties;
195198
}
196199

197200
public void addIncompeteParameter(AnnotatedParameter parameter) {
@@ -293,19 +296,21 @@ private <T extends AnnotatedMember> T _fixAccess(T member)
293296
return member;
294297
}
295298

296-
protected void verifyNonDup(AnnotatedWithParams newOne, int typeIndex, boolean explicit)
299+
/**
300+
* @return True if specified Creator is to be used
301+
*/
302+
protected boolean verifyNonDup(AnnotatedWithParams newOne, int typeIndex, boolean explicit)
297303
{
298304
final int mask = (1 << typeIndex);
299305
_hasNonDefaultCreator = true;
300306
AnnotatedWithParams oldOne = _creators[typeIndex];
301307
// already had an explicitly marked one?
302308
if (oldOne != null) {
303309
boolean verify;
304-
305310
if ((_explicitCreators & mask) != 0) { // already had explicitly annotated, leave as-is
306311
// but skip, if new one not annotated
307312
if (!explicit) {
308-
return;
313+
return false;
309314
}
310315
// both explicit: verify
311316
verify = true;
@@ -327,7 +332,7 @@ protected void verifyNonDup(AnnotatedWithParams newOne, int typeIndex, boolean e
327332
// otherwise, which one to choose?
328333
if (newType.isAssignableFrom(oldType)) {
329334
// new type more generic, use old
330-
return;
335+
return false;
331336
}
332337
// new type more specific, use it
333338
}
@@ -336,6 +341,7 @@ protected void verifyNonDup(AnnotatedWithParams newOne, int typeIndex, boolean e
336341
_explicitCreators |= mask;
337342
}
338343
_creators[typeIndex] = _fixAccess(newOne);
344+
return true;
339345
}
340346

341347
/*
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.fasterxml.jackson.databind.creators;
2+
3+
import com.fasterxml.jackson.annotation.*;
4+
5+
import com.fasterxml.jackson.databind.*;
6+
7+
public class Creator1476Test extends BaseMapTest
8+
{
9+
static final class SimplePojo {
10+
private final int intField;
11+
private final String stringField;
12+
13+
public SimplePojo(@JsonProperty("intField") int intField) {
14+
this(intField, "empty");
15+
}
16+
17+
public SimplePojo(@JsonProperty("stringField") String stringField) {
18+
this(-1, stringField);
19+
}
20+
21+
@JsonCreator
22+
public SimplePojo(@JsonProperty("intField") int intField, @JsonProperty("stringField") String stringField) {
23+
this.intField = intField;
24+
this.stringField = stringField;
25+
}
26+
27+
public int getIntField() {
28+
return intField;
29+
}
30+
31+
public String getStringField() {
32+
return stringField;
33+
}
34+
}
35+
36+
public void testConstructorChoice() throws Exception {
37+
ObjectMapper mapper = new ObjectMapper();
38+
SimplePojo pojo = mapper.readValue("{ \"intField\": 1, \"stringField\": \"foo\" }", SimplePojo.class);
39+
40+
assertEquals(1, pojo.getIntField());
41+
assertEquals("foo", pojo.getStringField());
42+
}
43+
}

0 commit comments

Comments
 (0)