Skip to content

Commit

Permalink
Merge branch '2.18'
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Apr 7, 2024
2 parents dfe9546 + b0da9dd commit 43c0813
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 1 deletion.
2 changes: 1 addition & 1 deletion release-notes/CREDITS-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -1772,6 +1772,6 @@ Oddbjørn Kvalsund (oddbjornkvalsund@github)
(2.17.1)

Teodor Danciu (teodord@github)
* Repored #4464: When `Include.NON_DEFAULT` setting is used, `isEmpty()` method is
* Reported #4464: When `Include.NON_DEFAULT` setting is used, `isEmpty()` method is
not called on the serializer
(2.18.0)
3 changes: 3 additions & 0 deletions release-notes/VERSION-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ Project: jackson-databind
String ".05": not a valid representation
(reported by @EAlf91)
(fix by @pjfanning)
#4441: `@JsonSetter(nulls = Nulls.SKIP)` doesn't work in some situations
(reported by @Asapin)
(fix by Joo-Hyuk K)
#4450: Empty QName deserialized as `null`
(reported by @winfriedgerlach)
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/tools/jackson/databind/deser/impl/FieldProperty.java
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,11 @@ public Object deserializeSetAndReturn(JsonParser p,
@Override
public void set(Object instance, Object value)
{
if (value == null) {
if (_skipNulls) {
return;
}
}
try {
_field.set(instance, value);
} catch (Exception e) {
Expand All @@ -196,6 +201,11 @@ public void set(Object instance, Object value)
@Override
public Object setAndReturn(Object instance, Object value)
{
if (value == null) {
if (_skipNulls) {
return instance;
}
}
try {
_field.set(instance, value);
} catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,11 @@ public Object deserializeSetAndReturn(JsonParser p,
@Override
public final void set(Object instance, Object value) throws JacksonException
{
if (value == null) {
if (_skipNulls) {
return;
}
}
try {
_setter.invoke(instance, value);
} catch (Exception e) {
Expand All @@ -186,6 +191,11 @@ public final void set(Object instance, Object value) throws JacksonException
@Override
public Object setAndReturn(Object instance, Object value) throws JacksonException
{
if (value == null) {
if (_skipNulls) {
return instance;
}
}
try {
Object result = _setter.invoke(instance, value);
return (result == null) ? instance : result;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
package tools.jackson.databind.deser.filter;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import org.junit.jupiter.api.Test;

import com.fasterxml.jackson.annotation.*;

import tools.jackson.databind.ObjectMapper;
import tools.jackson.databind.json.JsonMapper;
import tools.jackson.databind.testutil.DatabindTestUtil;

import static org.junit.jupiter.api.Assertions.assertNotNull;

// [databind#4441] @JsonSetter(nulls = Nulls.SKIP) doesn't work in some situations
public class SkipNulls4441Test
extends DatabindTestUtil
{
static class Middle {
@JsonSetter(nulls = Nulls.SKIP)
private final List<Inner> listInner = new ArrayList<>();
private final String field1;

@JsonCreator
public Middle(@JsonProperty("field1") String field1) {
this.field1 = field1;
}

public List<Inner> getListInner() {
return listInner;
}

public String getField1() {
return field1;
}
}

static class Inner {
private final String field1;

@JsonCreator
public Inner(@JsonProperty("field1") String field1) {
this.field1 = field1;
}

public String getField1() {
return field1;
}
}

static class MiddleSetter {
private List<InnerSetter> listInner = new ArrayList<>();
private final String field1;

@JsonCreator
public MiddleSetter(@JsonProperty("field1") String field1) {
this.field1 = field1;
}

@JsonSetter(nulls = Nulls.SKIP)
public void setListInner(List<InnerSetter> listInner) {
// null passed here
Objects.requireNonNull(listInner);
this.listInner = listInner;
}

public List<InnerSetter> getListInner() {
return listInner;
}

public String getField1() {
return field1;
}
}

static class InnerSetter {
private final String field1;

@JsonCreator
public InnerSetter(@JsonProperty("field1") String field1) {
this.field1 = field1;
}

public String getField1() {
return field1;
}
}

private final ObjectMapper objectMapper = JsonMapper.builder().build();

private final String NULL_ENDING_JSON = a2q("{" +
" 'field1': 'data', " +
" 'listInner': null " +
"}");

private final String NULL_BEGINNING_JSON = a2q("{" +
" 'listInner': null, " +
" 'field1': 'data' " +
"}");

@Test
public void testFields() throws Exception {
// Passes
// For some reason, if most-inner "list1" field is null in the end, it works
_testFieldNullSkip(NULL_ENDING_JSON);
// Fails
// But if it's null in the beginning, it doesn't work
_testFieldNullSkip(NULL_BEGINNING_JSON);
}

@Test
public void testMethods() throws Exception {
// Passes
// For some reason, if most-inner "list1" field is null in the end, it works
_testMethodNullSkip(NULL_ENDING_JSON);
// Fails
// But if it's null in the beginning, it doesn't work
_testMethodNullSkip(NULL_BEGINNING_JSON);
}

private void _testMethodNullSkip(String s) throws Exception {
MiddleSetter middle = objectMapper.readValue(s, MiddleSetter.class);

testMiddleSetter(middle);
}

private void _testFieldNullSkip(String s) throws Exception {
Middle middle = objectMapper.readValue(s, Middle.class);

testMiddle(middle);
}

private void testMiddle(Middle middle) {
validateNotNull(middle);
validateNotNull(middle.getField1());
validateNotNull(middle.getListInner());
}

private void testMiddleSetter(MiddleSetter middle) {
validateNotNull(middle);
validateNotNull(middle.getField1());
validateNotNull(middle.getListInner());
}

private static void validateNotNull(Object o) {
assertNotNull(o);
}
}

0 comments on commit 43c0813

Please sign in to comment.