[jackson-datatype-jdk8]value of Optional member type is null when property is missing in json string.

11 views
Skip to first unread message

charles chung

unread,
Jun 8, 2020, 12:33:32 PM6/8/20
to jackson-user
If in json string, the property is missing, and the corresponding Java type is Optional, the deserialized field value is null, where Optional.Empty is expected.

There is the code to reproduce this issue.

// I know that using Optional type in class field is generally regarded as an anti-pattern.


    public static class FooRequest {
        private Optional<Long> foo;

        public Optional<Long> getFoo() {
            return foo;
        }

        public void setFoo(Optional<Long> foo) {
            this.foo = foo;
        }
    }


    @Test
    public void testDeserializeOptional_property_missing() throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new Jdk8Module());
        FooRequest fooRequest = mapper.readValue("{}", FooRequest.class);
        // the issue : fooRequest.foo is null here, where Optional.Empty is expected
        Assert.assertFalse(fooRequest.getFoo().isPresent());
    }

    @Test
    public void testDeserializeOptional_property_isnull() throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new Jdk8Module());
        FooRequest fooRequest = mapper.readValue("{\"foo\":null}", FooRequest.class);
        Assert.assertFalse(fooRequest.getFoo().isPresent());
    }

Tatu Saloranta

unread,
Jun 8, 2020, 12:45:50 PM6/8/20
to jackson-user
On Mon, Jun 8, 2020 at 9:33 AM charles chung <charles...@gmail.com> wrote:
If in json string, the property is missing, and the corresponding Java type is Optional, the deserialized field value is null, where Optional.Empty is expected.


Yes, this is how Jackson works. Properties that are encountered are processed, and that is it.
Expectation is that if you want "default values", your POJO will assign them in declaration or constructor.

There is no attempt to check what might exist, with one exception: if you specify Creator method (constructor or static factory method annotated with `@JsonCreator`), then properties passed through it will have to be initialized somehow.

So if you want to force setting of `Optional` property with `Optional.empty()`, you should either make that assignment yourself by default (in field declaration or default constructor) OR use `@JsonCreator`. Latter has the benefit that you can also use `@JsonProperty(required = true)` to throw exception if the value is not included in json.

I hope this helps,

-+ Tatu +-
 
There is the code to reproduce this issue.

// I know that using Optional type in class field is generally regarded as an anti-pattern.


    public static class FooRequest {
        private Optional<Long> foo;

        public Optional<Long> getFoo() {
            return foo;
        }

        public void setFoo(Optional<Long> foo) {
            this.foo = foo;
        }
    }


    @Test
    public void testDeserializeOptional_property_missing() throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new Jdk8Module());
        FooRequest fooRequest = mapper.readValue("{}", FooRequest.class);
        // the issue : fooRequest.foo is null here, where Optional.Empty is expected
        Assert.assertFalse(fooRequest.getFoo().isPresent());
    }

    @Test
    public void testDeserializeOptional_property_isnull() throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new Jdk8Module());
        FooRequest fooRequest = mapper.readValue("{\"foo\":null}", FooRequest.class);
        Assert.assertFalse(fooRequest.getFoo().isPresent());
    }

--
You received this message because you are subscribed to the Google Groups "jackson-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jackson-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jackson-user/97734ab4-cebf-4646-a90d-aaf45960a2dao%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages