Mandrek
Mandrek

Reputation: 1211

JsonInclude.Include.NON_EMPTY not working

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

Upvotes: 0

Views: 264

Answers (1)

pochopsp
pochopsp

Reputation: 1015

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

Upvotes: 0

Related Questions