JsonInclude.Include.NON_EMPTY not working

82 views Asked by At

I am trying to add Null Check for my dto, but it's not working and everytime i am getting null value added in the dto. I am posting the dto structure here

@NoArgsConstructor
@AllArgsConstructor
@Data
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class SamplePreferenceResponse implements Serializable {

private String name;

private List<SamplePreferenceResponse.SpecialWeightage> specialWeightage;

@Data
public class SpecialWeightage implements Serializable {

    private Long id;
    private int check;
    private Long myAttributeId;
   }
 }

And i am using this operation which is giving me null value added in

name & specialWeightage

 myPreList.stream().filter(distinctByKey(SamplePreferenceResponseEntity :: getMyAttributeId))
                .forEach(samplePreferenceResponseEntity -> {
                    SamplePreferenceResponse samplePreferenceResponse = new SamplePreferenceResponse();
                        samplePreferenceResponse.setName(map.containsKey(samplePreferenceResponseEntity.getMyAttributeId()) ? map.get(samplePreferenceResponseEntity.getMyAttributeId()) : null);
                        samplePreferenceResponse.setSpecialWeightage(specialWeightage.get(samplePreferenceResponseEntity.getMyAttributeId()));
                    samplePreferenceResponseList.add(samplePreferenceResponse);
        });

I am not able to understand what i am missing here

1

There are 1 answers

0
pochopsp On

The com.fasterxml.jackson.annotation.JsonInclude annotation has only effect after serialization occurs, not before.

From @JsonInclude javadoc: "Annotation used to indicate when value of the annotated property (whenused for a field, method or constructor parameter), or allproperties of the annotated class, is to be serialized."

Serialization is when instances of the class are turned into a byte-stream (for example, when sending them in an HTTP response body or saved to a file).

I created a RestController in a Spring Web Application to show you the difference from what we have in Java and what we have AFTER serialization occurs:

@RestController
public class SampleController {

    @GetMapping
    public List<SamplePreferenceResponse> sample() {

        List<SamplePreferenceResponseEntity> myPreList = List.of(
            new SamplePreferenceResponseEntity(1L),
            new SamplePreferenceResponseEntity(1L),
            new SamplePreferenceResponseEntity(2L),
            new SamplePreferenceResponseEntity(3L)
        );
        List<SamplePreferenceResponse> samplePreferenceResponseList = new ArrayList<>();
        
        Map<Long, String> map = Map.of(
            1L, "foo",
            3L, "bar"
        );
        Map<Long, List<SamplePreferenceResponse.SpecialWeightage>> specialWeightage = Map.of(
                1L, List.of(new SamplePreferenceResponse().new SpecialWeightage()),
                3L, List.of(new SamplePreferenceResponse().new SpecialWeightage())
        );
        
        myPreList.stream().filter(distinctByKey(SamplePreferenceResponseEntity::getMyAttributeId))
                .forEach(samplePreferenceResponseEntity -> {
                    SamplePreferenceResponse samplePreferenceResponse = new SamplePreferenceResponse();
                    samplePreferenceResponse.setName(map.containsKey(samplePreferenceResponseEntity.getMyAttributeId()) ? map.get(samplePreferenceResponseEntity.getMyAttributeId()) : null);
                    samplePreferenceResponse.setSpecialWeightage(specialWeightage.get(samplePreferenceResponseEntity.getMyAttributeId()));
                    samplePreferenceResponseList.add(samplePreferenceResponse);
                });

        return samplePreferenceResponseList;
    }

    
    public static <T> Predicate<? super T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }

}

What we have in java:

Running it in debug mode, we can see that in samplePreferenceResponseList we have three objects, two (marked yellow) with name and specialWeightage not null (the ones that mapped ids 1L and 3L) and one (marked orange) with name and specialWeightage null (that was SamplePreferenceResponseEntity with id 2L): samplePreferenceResponseList content

What we have after serialization:

In the json array response, we have three json objects, two (marked yellow) with name and specialWeightage not null (the ones that mapped ids 1L and 3L) and one (marked orange) EMPTY, because JsonInclude annotation removed name and specialWeightage since they were both null (that was SamplePreferenceResponseEntity with id 2L): json array response content