Search code examples
javanulljacksonhashmapobjectmapper

Keep null fields of a POJO as keys in map java


I have a POJO and using object mapper to convert it into a map. I want the map to contain all fields of the POJO in it's entryset even if their value is null. So that entry might be null in the map I am creating.

Map<String, Object> oldDetails = objectMapper.convertValue(oldFields, Map.class);

I've tried using below snippet but that didn't help me.

objectMapper.setDefaultPropertyInclusion(JsonInclude.Value.construct(JsonInclude.Include.ALWAYS, JsonInclude.Include.ALWAYS));

Any other idea that I can use here?

My POJO:

@JsonInclude(NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class BaseFields {

    @JsonProperty("number") protected String number;
    @JsonProperty("name") protected String name;
    @JsonProperty("dob") protected String dob;

}

There are other classes inheriting from BaseFields such as.

@JsonInclude(NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class CustomerBaseFields extends BaseFields {
    @JsonProperty("email") protected String email;         
}

Now there is method that converts an instance of ChangedBaseFields into a map.

ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, true);
        objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
        objectMapper.setDefaultPropertyInclusion(JsonInclude.Value.construct(JsonInclude.Include.ALWAYS, JsonInclude.Include.ALWAYS));
        Map<String, Object> oldDetails = objectMapper.convertValue(baseFields, Map.class);

But say if a field like email is null in object, I'm not getting a key email in my map.


Solution

  • Here's simple code demonstrating that your code in fact works without any additional configuration with default ObjectMapper.

    package java17test;
    
    import com.fasterxml.jackson.databind.ObjectMapper;
    
    import java.util.Map;
    
    public class Test {
        public static void main(String[] args) {
            var objectMapper = new ObjectMapper();
            
            var oldFields = new TestClass();
            oldFields.setFirstName("first name");
    
            Map<?, ?> oldDetails = objectMapper.convertValue(oldFields, Map.class);
            oldDetails.forEach((key, value) -> System.out.println(key + "=" + value));
        }
    
        static class TestClass {
            private String firstName;
            private String lastName;
    
            public String getFirstName() {
                return firstName;
            }
    
            public void setFirstName(String firstName) {
                this.firstName = firstName;
            }
    
            public String getLastName() {
                return lastName;
            }
    
            public void setLastName(String lastName) {
                this.lastName = lastName;
            }
        }
    }
    

    Output:

    firstName=first name
    lastName=null