Skip to content

Commit aafba87

Browse files
authored
Try to fix #4626, #4630 (start with failing tests) (#4635)
1 parent d8857c1 commit aafba87

File tree

5 files changed

+86
-8
lines changed

5 files changed

+86
-8
lines changed

release-notes/VERSION-2.x

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ Project: jackson-databind
5959
(reported by Eduard G)
6060
#4617: Record property serialization order not preserved
6161
(reported by @GeorgiPetkov)
62+
#4626: `@JsonIgnore` on Record property ignored for deserialization, if
63+
there is getter override
64+
(reported by Sim Y-T)
65+
#4630: `@JsonIncludeProperties`, `@JsonIgnoreProperties` ignored when serializing
66+
Records, if there is getter override
67+
(reported by Sim Y-T)
6268
#4634: `@JsonAnySetter` not working when annotated on both constructor
6369
parameter & field
6470
(contributed by Sim Y-T)

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

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -438,9 +438,9 @@ protected void collectAll()
438438
// altogether (unless we find a good reason to detect them)
439439
// 17-Apr-2023: Need Records' fields for serialization for cases
440440
// like [databind#3628], [databind#3895] and [databind#3992]
441-
if (!isRecordType() || _forSerialization) {
442-
_addFields(props); // note: populates _fieldRenameMappings
443-
}
441+
// 22-Jul-2024, tatu: ... and for deserialization sometimes too [databind#4626]
442+
_addFields(props); // note: populates _fieldRenameMappings
443+
444444
_addMethods(props);
445445
// 25-Jan-2016, tatu: Avoid introspecting (constructor-)creators for non-static
446446
// inner classes, see [databind#1502]
@@ -455,7 +455,7 @@ protected void collectAll()
455455
// since logic relies on knowing exactly which accessor has which annotation
456456
_removeUnwantedProperties(props);
457457
// and then remove unneeded accessors (wrt read-only, read-write)
458-
_removeUnwantedAccessor(props);
458+
_removeUnwantedAccessors(props);
459459

460460
// Rename remaining properties
461461
_renameProperties(props);
@@ -485,6 +485,14 @@ protected void collectAll()
485485
property.trimByVisibility();
486486
}
487487

488+
// 22-Jul-2024, tatu: And now drop Record Fields once their effect
489+
// (annotations) has been applied. But just for deserialization
490+
if (_isRecordType && !_forSerialization) {
491+
for (POJOPropertyBuilder property : props.values()) {
492+
property.removeFields();
493+
}
494+
}
495+
488496
// and, if required, apply wrapper name: note, MUST be done after
489497
// annotations are merged.
490498
if (_config.isEnabled(MapperFeature.USE_WRAPPER_NAME_AS_PROPERTY_NAME)) {
@@ -1299,12 +1307,12 @@ protected void _removeUnwantedProperties(Map<String, POJOPropertyBuilder> props)
12991307
* based on read/write settings and rules for "pulling in" accessors
13001308
* (or not).
13011309
*/
1302-
protected void _removeUnwantedAccessor(Map<String, POJOPropertyBuilder> props)
1310+
protected void _removeUnwantedAccessors(Map<String, POJOPropertyBuilder> props)
13031311
{
13041312
// 15-Jan-2023, tatu: Avoid pulling in mutators for Records; Fields mostly
13051313
// since there should not be setters.
1306-
final boolean inferMutators = !isRecordType()
1307-
&& _config.isEnabled(MapperFeature.INFER_PROPERTY_MUTATORS);
1314+
// 22-Jul-2024, tatu: Actually do pull them to fix [databind#4630]
1315+
final boolean inferMutators = _config.isEnabled(MapperFeature.INFER_PROPERTY_MUTATORS);
13081316
Iterator<POJOPropertyBuilder> it = props.values().iterator();
13091317

13101318
while (it.hasNext()) {

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -996,6 +996,15 @@ public void removeConstructors() {
996996
_ctorParameters = null;
997997
}
998998

999+
/**
1000+
* Mutator that will simply drop any fields property may have.
1001+
*
1002+
* @since 2.18
1003+
*/
1004+
public void removeFields() {
1005+
_fields = null;
1006+
}
1007+
9991008
/**
10001009
* Method called to trim unnecessary entries, such as implicit
10011010
* getter if there is an explict one available. This is important

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ void add(Recursion recursion) {
3939

4040
// [databind#3992]
4141
@Test
42-
public void testHelloRecord() throws Exception {
42+
public void testHelloRecord3992() throws Exception {
4343
Recursion beanWithRecursion = new Recursion();
4444
beanWithRecursion.add(beanWithRecursion);
4545
String json = MAPPER.writer()
@@ -50,4 +50,14 @@ public void testHelloRecord() throws Exception {
5050
HelloRecord result = MAPPER.readValue(json, HelloRecord.class);
5151
assertNotNull(result);
5252
}
53+
54+
// [databind#4626]
55+
@Test
56+
public void testDeserializeWithOverride4626() throws Exception {
57+
HelloRecord expected = new HelloRecord("hello", null);
58+
59+
assertEquals(expected, MAPPER.readValue(a2q("{'text':'hello'}"), HelloRecord.class));
60+
assertEquals(expected, MAPPER.readValue(a2q("{'text':'hello','hidden':null}"), HelloRecord.class));
61+
assertEquals(expected, MAPPER.readValue(a2q("{'text':'hello','hidden':{'all': []}}"), HelloRecord.class));
62+
}
5363
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.fasterxml.jackson.databind.records;
2+
3+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4+
import com.fasterxml.jackson.annotation.JsonIncludeProperties;
5+
import com.fasterxml.jackson.databind.ObjectMapper;
6+
import com.fasterxml.jackson.databind.testutil.DatabindTestUtil;
7+
import org.junit.jupiter.api.Test;
8+
9+
import static org.junit.jupiter.api.Assertions.assertEquals;
10+
11+
public class RecordWithOverriddenInclude4630Test extends DatabindTestUtil
12+
{
13+
record Id2Name(int id, String name) {
14+
}
15+
16+
record RecordWithJsonIncludeProperties(@JsonIncludeProperties("id") Id2Name child) {
17+
@Override
18+
public Id2Name child() {
19+
return child;
20+
}
21+
}
22+
23+
record RecordWithJsonIgnoreProperties(@JsonIgnoreProperties("name") Id2Name child) {
24+
@Override
25+
public Id2Name child() {
26+
return child;
27+
}
28+
}
29+
30+
private final ObjectMapper MAPPER = newJsonMapper();
31+
32+
// [databind#4630]
33+
@Test
34+
public void testSerializeJsonIncludeProperties() throws Exception {
35+
String json = MAPPER.writeValueAsString(new RecordWithJsonIncludeProperties(new Id2Name(123, "Bob")));
36+
assertEquals(a2q("{'child':{'id':123}}"), json);
37+
}
38+
39+
// [databind#4630]
40+
@Test
41+
public void testSerializeJsonIgnoreProperties() throws Exception {
42+
String json = MAPPER.writeValueAsString(new RecordWithJsonIgnoreProperties(new Id2Name(123, "Bob")));
43+
assertEquals(a2q("{'child':{'id':123}}"), json);
44+
}
45+
}

0 commit comments

Comments
 (0)