Skip to content

Commit a0cd172

Browse files
committed
Merge branch '2.x' into 3.0
2 parents fa34d9d + 1fe6ee7 commit a0cd172

File tree

4 files changed

+65
-4
lines changed

4 files changed

+65
-4
lines changed

release-notes/VERSION

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ Versions: 3.x (for earlier see VERSION-2.x)
1414
#5393: `@JsonAnyGetter` property gets included in generated schema
1515
(reported by @victor-noel-pfx)
1616
(fix by Joo-Hyuk K)
17+
#5398: `@JsonProperty.value` + `@JsonIgnore` on setter does not work
18+
anymore since 2.18.4
19+
(reported by @victor-noel-pfx)
20+
(fix by @cowtowncoder, w/ Claude code)
1721
#5401: Regression with `@JsonCreator` that returns `null` for empty strings
1822
(fix contributed by Joost K)
1923
#5408: Jackson 3 `JsonNode#required(java.lang.String)` throws `JsonNodeException`

release-notes/VERSION-2.x

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,14 @@ Project: jackson-databind
1919
customizability
2020
(contributed by @wrongwrong)
2121
#5361: Fix Maven SBOM publishing
22+
#5398: `@JsonProperty.value` + `@JsonIgnore` on setter does not work
23+
anymore since 2.18.4
24+
(reported by @victor-noel-pfx)
25+
(fix by @cowtowncoder, w/ Claude code)
2226

2327
2.20.2 (not yet released)
2428

25-
#5393: `@JsonAnyGetter property gets included in generated schema since 2.19.0`
29+
#5393: `@JsonAnyGetter` property gets included in generated schema since 2.19.0
2630
(reported by @victor-noel-pfx)
2731
(fix by Joo-Hyuk K)
2832

src/main/java/tools/jackson/databind/introspect/POJOPropertiesCollector.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1514,13 +1514,19 @@ protected void _renameProperties(Map<String, POJOPropertyBuilder> props)
15141514
POJOPropertyBuilder prop = entry.getValue();
15151515

15161516
// 10-Apr-2025: [databind#4628] skip properties that are marked to be ignored
1517-
// TODO: we are using implicit name, is that ok?
1517+
// 19-Nov-2025: [databind#5398] BUT do not skip if property has explicit names
1518+
// on accessors that are NOT ignored (e.g., @JsonProperty on getter but @JsonIgnore on setter).
1519+
// NOTE: For Records we need to be more conservative as constructor parameters may have
1520+
// both annotations but generated accessors don't always inherit @JsonIgnore
15181521
if (_ignoredPropertyNames != null && _ignoredPropertyNames.contains(prop.getName())) {
1519-
continue;
1522+
// For Records: always skip (safer due to annotation inheritance issues)
1523+
// For regular classes: only skip if NO explicit names on non-ignored accessors
1524+
if (isRecordType() || !prop.anyExplicitsWithoutIgnoral()) {
1525+
continue;
1526+
}
15201527
}
15211528

15221529
Collection<PropertyName> l = prop.findExplicitNames();
1523-
15241530
// no explicit names? Implicit one is fine as is
15251531
if (l.isEmpty()) {
15261532
continue;
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package tools.jackson.databind.introspect;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import com.fasterxml.jackson.annotation.*;
6+
7+
import tools.jackson.databind.*;
8+
import tools.jackson.databind.testutil.DatabindTestUtil;
9+
10+
import static org.junit.jupiter.api.Assertions.*;
11+
12+
// [databind#5398] @JsonProperty on getter with @JsonIgnore on setter
13+
// causes deserialization to fail since 2.18.4
14+
public class JsonPropertyRename5398Test extends DatabindTestUtil
15+
{
16+
static class Test5398 {
17+
private String prop = "someValue";
18+
19+
@JsonProperty(value = "renamedProp")
20+
public String getProp() {
21+
return prop;
22+
}
23+
24+
@JsonIgnore
25+
public void setProp(String prop) {
26+
this.prop = prop;
27+
}
28+
}
29+
30+
private final ObjectMapper MAPPER = newJsonMapper();
31+
32+
@Test
33+
public void testRenamedPropertyWithIgnoredSetter5398()
34+
{
35+
Test5398 original = new Test5398();
36+
String json = MAPPER.writeValueAsString(original);
37+
38+
// Should serialize with renamed property
39+
assertEquals("{\"renamedProp\":\"someValue\"}", json);
40+
41+
// Should be able to deserialize back (setter is ignored, so field remains default)
42+
Test5398 result = MAPPER.readValue(json, Test5398.class);
43+
assertNotNull(result);
44+
// Since setter is ignored, the deserialized object should have the default value
45+
assertEquals("someValue", result.getProp());
46+
}
47+
}

0 commit comments

Comments
 (0)