Skip to content

Commit 2465ede

Browse files
committed
Merge branch '2.17' into 2.18
2 parents d6f0a9e + 01f24af commit 2465ede

File tree

4 files changed

+173
-0
lines changed

4 files changed

+173
-0
lines changed

release-notes/VERSION-2.x

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ Project: jackson-databind
2323
String ".05": not a valid representation
2424
(reported by @EAlf91)
2525
(fix by @pjfanning)
26+
#4441: `@JsonSetter(nulls = Nulls.SKIP)` doesn't work in some situations
27+
(reported by @Asapin)
28+
(fix by Joo-Hyuk K)
2629
#4450: Empty QName deserialized as `null`
2730
(reported by @winfriedgerlach)
2831

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,11 @@ public Object deserializeSetAndReturn(JsonParser p,
186186
@Override
187187
public void set(Object instance, Object value) throws IOException
188188
{
189+
if (value == null) {
190+
if (_skipNulls) {
191+
return;
192+
}
193+
}
189194
try {
190195
_field.set(instance, value);
191196
} catch (Exception e) {
@@ -197,6 +202,11 @@ public void set(Object instance, Object value) throws IOException
197202
@Override
198203
public Object setAndReturn(Object instance, Object value) throws IOException
199204
{
205+
if (value == null) {
206+
if (_skipNulls) {
207+
return instance;
208+
}
209+
}
200210
try {
201211
_field.set(instance, value);
202212
} catch (Exception e) {

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,11 @@ public Object deserializeSetAndReturn(JsonParser p,
178178
@Override
179179
public final void set(Object instance, Object value) throws IOException
180180
{
181+
if (value == null) {
182+
if (_skipNulls) {
183+
return;
184+
}
185+
}
181186
try {
182187
_setter.invoke(instance, value);
183188
} catch (Exception e) {
@@ -189,6 +194,11 @@ public final void set(Object instance, Object value) throws IOException
189194
@Override
190195
public Object setAndReturn(Object instance, Object value) throws IOException
191196
{
197+
if (value == null) {
198+
if (_skipNulls) {
199+
return instance;
200+
}
201+
}
192202
try {
193203
Object result = _setter.invoke(instance, value);
194204
return (result == null) ? instance : result;
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
package com.fasterxml.jackson.databind.deser.filter;
2+
3+
import com.fasterxml.jackson.annotation.JsonCreator;
4+
import com.fasterxml.jackson.annotation.JsonProperty;
5+
import com.fasterxml.jackson.annotation.JsonSetter;
6+
import com.fasterxml.jackson.annotation.Nulls;
7+
import com.fasterxml.jackson.databind.ObjectMapper;
8+
import com.fasterxml.jackson.databind.json.JsonMapper;
9+
import org.junit.jupiter.api.Test;
10+
11+
import java.util.ArrayList;
12+
import java.util.List;
13+
import java.util.Objects;
14+
15+
import static com.fasterxml.jackson.databind.BaseTest.a2q;
16+
import static org.junit.jupiter.api.Assertions.assertNotNull;
17+
18+
// [databind#4441] @JsonSetter(nulls = Nulls.SKIP) doesn't work in some situations
19+
public class SkipNulls4441Test {
20+
21+
static class Middle {
22+
@JsonSetter(nulls = Nulls.SKIP)
23+
private final List<Inner> listInner = new ArrayList<>();
24+
private final String field1;
25+
26+
@JsonCreator
27+
public Middle(@JsonProperty("field1") String field1) {
28+
this.field1 = field1;
29+
}
30+
31+
public List<Inner> getListInner() {
32+
return listInner;
33+
}
34+
35+
public String getField1() {
36+
return field1;
37+
}
38+
}
39+
40+
static class Inner {
41+
private final String field1;
42+
43+
@JsonCreator
44+
public Inner(@JsonProperty("field1") String field1) {
45+
this.field1 = field1;
46+
}
47+
48+
public String getField1() {
49+
return field1;
50+
}
51+
}
52+
53+
static class MiddleSetter {
54+
private List<InnerSetter> listInner = new ArrayList<>();
55+
private final String field1;
56+
57+
@JsonCreator
58+
public MiddleSetter(@JsonProperty("field1") String field1) {
59+
this.field1 = field1;
60+
}
61+
62+
@JsonSetter(nulls = Nulls.SKIP)
63+
public void setListInner(List<InnerSetter> listInner) {
64+
// null passed here
65+
Objects.requireNonNull(listInner);
66+
this.listInner = listInner;
67+
}
68+
69+
public List<InnerSetter> getListInner() {
70+
return listInner;
71+
}
72+
73+
public String getField1() {
74+
return field1;
75+
}
76+
}
77+
78+
static class InnerSetter {
79+
private final String field1;
80+
81+
@JsonCreator
82+
public InnerSetter(@JsonProperty("field1") String field1) {
83+
this.field1 = field1;
84+
}
85+
86+
public String getField1() {
87+
return field1;
88+
}
89+
}
90+
91+
private final ObjectMapper objectMapper = JsonMapper.builder().build();
92+
93+
private final String NULL_ENDING_JSON = a2q("{" +
94+
" 'field1': 'data', " +
95+
" 'listInner': null " +
96+
"}");
97+
98+
private final String NULL_BEGINNING_JSON = a2q("{" +
99+
" 'listInner': null, " +
100+
" 'field1': 'data' " +
101+
"}");
102+
103+
@Test
104+
public void testFields() throws Exception {
105+
// Passes
106+
// For some reason, if most-inner "list1" field is null in the end, it works
107+
_testFieldNullSkip(NULL_ENDING_JSON);
108+
// Fails
109+
// But if it's null in the beginning, it doesn't work
110+
_testFieldNullSkip(NULL_BEGINNING_JSON);
111+
}
112+
113+
@Test
114+
public void testMethods() throws Exception {
115+
// Passes
116+
// For some reason, if most-inner "list1" field is null in the end, it works
117+
_testMethodNullSkip(NULL_ENDING_JSON);
118+
// Fails
119+
// But if it's null in the beginning, it doesn't work
120+
_testMethodNullSkip(NULL_BEGINNING_JSON);
121+
}
122+
123+
private void _testMethodNullSkip(String s) throws Exception {
124+
MiddleSetter middle = objectMapper.readValue(s, MiddleSetter.class);
125+
126+
testMiddleSetter(middle);
127+
}
128+
129+
private void _testFieldNullSkip(String s) throws Exception {
130+
Middle middle = objectMapper.readValue(s, Middle.class);
131+
132+
testMiddle(middle);
133+
}
134+
135+
private void testMiddle(Middle middle) {
136+
validateNotNull(middle);
137+
validateNotNull(middle.getField1());
138+
validateNotNull(middle.getListInner());
139+
}
140+
141+
private void testMiddleSetter(MiddleSetter middle) {
142+
validateNotNull(middle);
143+
validateNotNull(middle.getField1());
144+
validateNotNull(middle.getListInner());
145+
}
146+
147+
private static void validateNotNull(Object o) {
148+
assertNotNull(o);
149+
}
150+
}

0 commit comments

Comments
 (0)