Skip to content

Commit 3de5307

Browse files
authored
fix(#4218): avoid duplicate injection on fields (#5224)
1 parent d9b8d8d commit 3de5307

File tree

6 files changed

+43
-24
lines changed

6 files changed

+43
-24
lines changed

release-notes/CREDITS-2.x

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1869,6 +1869,9 @@ wrongwrong (@k163377)
18691869
* Contributed fix for #5202: #5202: `JsonSetter.contentNulls` ignored for `Object[]`,
18701870
`String[]` and `Collection<String>`
18711871
(2.19.2)
1872+
* Reported #4218: If `@JacksonInject` is specified for field and deserialized by
1873+
the Creator, the inject process will be executed twice
1874+
(2.20.0)
18721875
18731876
Bernd Ahlers (@bernd)
18741877
* Reported #4742: Deserialization with Builder, External type id, `@JsonCreator` failing
@@ -1952,6 +1955,17 @@ Eddú Meléndez Gonzales (@eddumelendez)
19521955
(2.19.2)
19531956
19541957
Giulio Longfils (@giulong)
1958+
* Contributed #2678: `@JacksonInject` added to property overrides value from the JSON
1959+
even if `useInput` is `OptBoolean.TRUE`
1960+
(2.20.0)
19551961
* Contributed #3072: Allow specifying `@JacksonInject` does not fail when there's no
19561962
corresponding value
19571963
(2.20.0)
1964+
* Contributed #4218: If `@JacksonInject` is specified for field and deserialized by
1965+
the Creator, the inject process will be executed twice
1966+
(2.20.0)
1967+
1968+
Plamen Tanov (@ptanov)
1969+
* Reported #2678: `@JacksonInject` added to property overrides value from the JSON
1970+
even if `useInput` is `OptBoolean.TRUE`
1971+
(2.20.0)

release-notes/VERSION-2.x

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,16 @@ Project: jackson-databind
66

77
Not yet released
88

9+
#2678: `@JacksonInject` added to property overrides value from the JSON
10+
even if `useInput` is `OptBoolean.TRUE`
11+
(reported by Plamen T)
12+
(fix by Giulio L)
913
#2692: Should never call `set()` on setterless property during deserialization
1014
(reported by @lbonco)
15+
#4218: If `@JacksonInject` is specified for field and deserialized by the Creator,
16+
the inject process will be executed twice
17+
(reported by @wrongwrong)
18+
(fix by Giulio L)
1119
#5237: Failing `@JsonMerge` with a custom Map with a `@JsonCreator` constructor
1220
(reported by @nlisker)
1321
#5238: Immutable classes with `@JsonIdentityInfo` can be deserialized; records cannot

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1282,6 +1282,20 @@ protected void _addInjectables(Map<String, POJOPropertyBuilder> props)
12821282
}
12831283
_doAddInjectable(_annotationIntrospector.findInjectableValue(m), m);
12841284
}
1285+
1286+
// 21-Aug-2025, tatu: [databind#4218] avoid duplicate injectables
1287+
if (_injectables != null) {
1288+
for (POJOPropertyBuilder creatorProperty : _creatorProperties) {
1289+
if (creatorProperty == null) {
1290+
continue;
1291+
}
1292+
final AnnotatedParameter parameter = creatorProperty.getConstructorParameter();
1293+
JacksonInject.Value injectable = _annotationIntrospector.findInjectableValue(parameter);
1294+
if (injectable != null) {
1295+
_injectables.remove(injectable.getId());
1296+
}
1297+
}
1298+
}
12851299
}
12861300

12871301
protected void _doAddInjectable(JacksonInject.Value injectable, AnnotatedMember m)

src/test-jdk17/java/com/fasterxml/jackson/databind/records/RecordBasicsTest.java

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -179,29 +179,16 @@ public void testDeserializeJsonRename() throws Exception {
179179
assertEquals(new RecordWithRename(123, "Bob"), value);
180180
}
181181

182-
/**
183-
* This test-case is just for documentation purpose:
184-
* GOTCHA: Annotations on header will be propagated to the field, leading to this failure.
185-
*
186-
* @see #testDeserializeConstructorInjectRecord()
187-
*/
182+
// Confirmation of fix of [databind#4218]
188183
@Test
189-
public void testDeserializeHeaderInjectRecord_WillFail() throws Exception {
184+
public void testDeserializeHeaderInjectRecord4218() throws Exception {
190185
ObjectReader reader = MAPPER.readerFor(RecordWithHeaderInject.class)
191186
.with(new InjectableValues.Std().addValue(String.class, "Bob"));
192-
193-
try {
194-
reader.readValue("{\"id\":123}");
195-
196-
fail("should not pass");
197-
} catch (IllegalArgumentException e) {
198-
verifyException(e, "RecordWithHeaderInject#name");
199-
verifyException(e, "Can not set final java.lang.String field");
200-
}
187+
assertNotNull(reader.readValue("{\"id\":123}"));
201188
}
202189

203190
@Test
204-
public void testDeserializeConstructorInjectRecord() throws Exception {
191+
public void testDeserializeConstructorInjectRecord4218() throws Exception {
205192
ObjectReader reader = MAPPER.readerFor(RecordWithConstructorInject.class)
206193
.with(new InjectableValues.Std().addValue(String.class, "Bob"));
207194
RecordWithConstructorInject value = reader.readValue("{\"id\":123}");

src/test/java/com/fasterxml/jackson/databind/tofix/JacksonInject2678Test.java renamed to src/test/java/com/fasterxml/jackson/databind/deser/inject/JacksonInject2678Test.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.fasterxml.jackson.databind.tofix;
1+
package com.fasterxml.jackson.databind.deser.inject;
22

33
import java.util.Objects;
44

@@ -10,7 +10,6 @@
1010
import com.fasterxml.jackson.databind.ObjectMapper;
1111
import com.fasterxml.jackson.databind.json.JsonMapper;
1212
import com.fasterxml.jackson.databind.testutil.DatabindTestUtil;
13-
import com.fasterxml.jackson.databind.testutil.failure.JacksonTestFailureExpected;
1413

1514
import static org.junit.jupiter.api.Assertions.assertEquals;
1615

@@ -41,7 +40,6 @@ public String getField2() {
4140
}
4241

4342
// [databind#2678]
44-
@JacksonTestFailureExpected
4543
@Test
4644
void readValueInjectables() throws Exception {
4745
final InjectableValues injectableValues =

src/test/java/com/fasterxml/jackson/databind/tofix/JacksonInject4218Test.java renamed to src/test/java/com/fasterxml/jackson/databind/deser/inject/JacksonInject4218Test.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.fasterxml.jackson.databind.tofix;
1+
package com.fasterxml.jackson.databind.deser.inject;
22

33
import org.junit.jupiter.api.Test;
44

@@ -8,7 +8,6 @@
88

99
import com.fasterxml.jackson.databind.*;
1010
import com.fasterxml.jackson.databind.testutil.DatabindTestUtil;
11-
import com.fasterxml.jackson.databind.testutil.failure.JacksonTestFailureExpected;
1211

1312
import static org.junit.jupiter.api.Assertions.assertEquals;
1413

@@ -51,9 +50,8 @@ public Object findInjectableValue(
5150
}
5251

5352
// [databind#4218]
54-
@JacksonTestFailureExpected
5553
@Test
56-
void injectFail4218() throws Exception
54+
void injectNoDups4218() throws Exception
5755
{
5856
ObjectReader reader = newJsonMapper()
5957
.readerFor(Dto.class)

0 commit comments

Comments
 (0)