Skip to content

Commit 1fe6ee7

Browse files
authored
Fix #5398: ignore + rename (#5410)
1 parent 08a76e5 commit 1fe6ee7

File tree

3 files changed

+59
-3
lines changed

3 files changed

+59
-3
lines changed

release-notes/VERSION-2.x

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ 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

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

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

15621562
// 10-Apr-2025: [databind#4628] skip properties that are marked to be ignored
1563-
// TODO: we are using implicit name, is that ok?
1563+
// 19-Nov-2025: [databind#5398] BUT do not skip if property has explicit names
1564+
// on accessors that are NOT ignored (e.g., @JsonProperty on getter but @JsonIgnore on setter).
1565+
// NOTE: For Records we need to be more conservative as constructor parameters may have
1566+
// both annotations but generated accessors don't always inherit @JsonIgnore
15641567
if (_ignoredPropertyNames != null && _ignoredPropertyNames.contains(prop.getName())) {
1565-
continue;
1568+
// For Records: always skip (safer due to annotation inheritance issues)
1569+
// For regular classes: only skip if NO explicit names on non-ignored accessors
1570+
if (isRecordType() || !prop.anyExplicitsWithoutIgnoral()) {
1571+
continue;
1572+
}
15661573
}
15671574

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

0 commit comments

Comments
 (0)