Skip to content

For an absent property Jackson injects NullNode instead of null to a JsonNode-typed constructor argument of a @ConstructorProperties-annotated constructor #3214

@robvarga

Description

@robvarga

Describe the bug
When using @ConstructorProperties-annotated constructor to deserialize type, for an attribute of type JsonNode which is absent from the deserialized JSON, a NullJsonNode is passed to the constructor instead of null reference.

I would like to know if there is a workaround (e.g. some annotation indicating what to do for absent properties, or configuring some alternative deserializer on a per-property basis which is able to deal with this) for this issue which works with a constructor and final attributes instead of having to resort to non-final attributes and setters.
Since our project is on 2.7.5 at the moment, I would particularly be intereted if there is a workaround for 2.7.x which allows me to inject null instead of this NullNode at least on a per object basis if not on a per-property basis.

If there is no workaround, then this should probably be fixed or a workaround should be provided which works with final attributes and @ConstructorProperties-annotated constructor.

Version information
Which Jackson version(s) was this for?
Reproduced with 2.12.4, 2.9.8 and 2.7.5

To Reproduce
If you have a way to reproduce this with:

package jacksontests;
import java.beans.ConstructorProperties;
import org.junit.Assert;
import org.junit.Test;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JsonNodeNullTest {

    public static class TestClass {

        private final JsonNode nodeFromConstructor;
        private JsonNode nodeFromSetter;

        @ConstructorProperties("nodeFromConstructor")
        public TestClass(JsonNode nodeFromConstructor) {
            this.nodeFromConstructor = nodeFromConstructor;
        }

        public JsonNode getNodeFromSetter() {
            return nodeFromSetter;
        }

        public void setNodeFromSetter(JsonNode nodeFromSetter) {
            this.nodeFromSetter = nodeFromSetter;
        }

        public JsonNode getNodeFromConstructor() {
            return nodeFromConstructor;
        }
    }

    @Test
    public void testJsonNodeNulls() throws Exception {
        TestClass res = new ObjectMapper().readValue("{}", TestClass.class);
        Assert.assertNotNull(res);
        Assert.assertNull(res.getNodeFromSetter());
        Assert.assertNull(res.getNodeFromConstructor());
    }
}

Expected behavior
The unit test fails as res.getNodeFromConstructor() returns a NullNode instead of null.
It should return null identically to the property which is setter-populated. (The setter does not get called).

Additional context

Metadata

Metadata

Assignees

No one assigned

    Labels

    has-failing-testIndicates that there exists a test case (under `failing/`) to reproduce the issue

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions