question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

JsonInclude.ALWAYS not honored by ObjectMapper.convertValue(...)

See original GitHub issue

A JSON property of type Map with annotation @JsonInclude(JsonInclude.Include.ALWAYS) gets populated wrongly (missing entries with null values) when using ObjectMapper.convertValue from a Map to the type containing the JsonProperty.

Here is a full reproduction scenario where Pojo is the type containing the JsonProperty:

import java.util.LinkedHashMap;
import java.util.Map;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class Example {

    private static class Pojo {
        @JsonProperty("name1")
        String name1;

        @JsonProperty("name2")
        String name2;

        @JsonProperty("other")
        @JsonInclude(JsonInclude.Include.ALWAYS)
        Map<String, Object> otherInfo;
    }

    public static void main(String[] args) throws Exception {
        final Pojo pojo1 = new Pojo();
        pojo1.name1 = "hello";
        pojo1.name2 = null;
        pojo1.otherInfo = new LinkedHashMap<>();
        pojo1.otherInfo.put("foo", "bar");
        pojo1.otherInfo.put("baz", null);
        
        System.out.println("pojo1:\t" + pojo1.otherInfo);

        final ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

        final String str = mapper.writeValueAsString(pojo1);
        final Map<?, ?> map = mapper.readValue(str, Map.class);
        System.out.println("map:\t" + map);
        
        final Pojo pojo2 = mapper.convertValue(map, Pojo.class);
        
        System.out.println("pojo2:\t" + pojo2.otherInfo);
    }
}

Expected output:

pojo1:	{foo=bar, baz=null}
map:	{name1=hello, other={foo=bar, baz=null}}
pojo2:	{foo=bar, baz=null}

Actual output:

pojo1:	{foo=bar, baz=null}
map:	{name1=hello, other={foo=bar, baz=null}}
pojo2:	{foo=bar}\

I am using Jackson databind version 2.9.4.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
cowtowncodercommented, Feb 14, 2018

It is not a work-around but expected behavior.

Ine additional note, your earlier setting was equivalent to:

mapper.setDefaultPropertyInclusion(JsonInclude.Value.construct(Include.NON_NULL,
    Include.NON_NULL);

which indicates that all null property values are to be excluded (first) as well as all content values (values of Map entries). If you do not want latter, it has to be changed.

Also note that @JsonInclude actually accepts two properties as well:

@JsonInclude(value = Include.NON_NULL, contents = Include.ALWAYS)

but if one (or both) are omitted, that value defaults to global inclusion base (one set with setDefaultPropertyInclusion).

0reactions
kaspersorensencommented, Feb 14, 2018

OK it seems that your suggested change works well for my scenario:

mapper.setDefaultPropertyInclusion(JsonInclude.Value.construct(Include.NON_NULL,
    Include.ALWAYS);

So I’m fine with closing this issue. It just seemed counter-intuitive to me, would be nice to have an annotation specifically for Map objects maybe. So that this different behavior can be controlled on the Pojo member level.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Keep null fields of a POJO as keys in map java - Stack Overflow
ALWAYS, JsonInclude.Include.ALWAYS)); Map<String, Object> oldDetails = objectMapper.convertValue(baseFields, Map.class);. But say if a field ...
Read more >
ObjectMapper (jackson-databind 2.9.8 API) - javadoc.io
Method to deserialize JSON content into a non-container type (it can be an array type, however): typically a bean, array or a wrapper...
Read more >
Spring Boot: Customize the Jackson ObjectMapper - Baeldung
In this tutorial, we took a look at several methods to configure the JSON serialization options when using Spring Boot. We saw two...
Read more >
Definitive Guide to Jackson ObjectMapper - Serialize and ...
In this detailed guide - learn everything you need to know about ObjectMapper. Convert JSON to and from Java POJOs, implement custom ...
Read more >
Flexible immutability with Jackson and Lombok - Luminis
Some annotations do not combine well with super classes ... This is often the case when working with Elasticsearch, which allows for either ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found