Search code examples
javanullpointerexceptionmicroservicesdto

Java Spring doesn't return DTO objects if null?


I have a Java implementation Override method which returns DTO object results from 2 microservices depending on entered parameters.

I am able to get filtered search results however where the 2nd service conditions were not met I receive 'null' I would want to achieve a results where null objects are not returned whatsoever.How am I able to return results which meet all specified parameters?

Below I have provided screenshot of response I receive using "Swagger" and the code snipped which does all the magic.

Would I require to use ObjectMapper or something like @JsonInclude(Include.NON_NULL), however can I use it within service implantation and with DTO objects?

Any further suggestions or idea bouncing would be appreciated.

I have further build on my previous question Java pass variable into mapped DTO method?

Swagger response:

enter image description here

Code snippet:

    @Override
public Page<ProfileCreditDTO> findProfileBySelectedParameters(String username, Integer gender, Integer profileType, Integer orientation, Boolean online, Double profileCredit, Integer creditMode, Double creditTotal, Pageable pageable) {
    Page<Profile> searchData= profileRepository.findByAllParameters(username, gender, profileType, orientation, online, pageable);
    Page<ProfileCreditDTO> searchProfileData=null;
    if(searchData != null)
        searchProfileData = searchData.map(x -> this.convertProfileToProfileCreditDTO(x, profileCredit, creditMode, creditTotal));
    return searchProfileData;
}


public ProfileCreditDTO convertProfileToProfileCreditDTO(final Profile theProfile, Double profileCredit, Integer creditMode, Double creditTotal)  {
    if(theProfile == null)
        return null;
    ProfileCreditDTO theDTO= new ProfileCreditDTO();
    theDTO.setProfile(theProfile);
    CreditDTO theCreditDto = profileCreditClient.findClientByProfileId(theProfile.getId(), profileCredit, creditMode, creditTotal);
    log.error(String.valueOf(theCreditDto));
    if (theCreditDto != null)
        theDTO.setCredit(theCreditDto);
    else {
        return null;
    }

    return theDTO;
}

Updated

I have tried adding @JsonInclude(Include.NON_NULL) into ProfileCredit DTO still nothing, also have added same thing into CreditDTO.

ProfileCredit DTO:

 @Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ProfileCreditDTO {
    // profile fields
    private Long profileId;
    @Size(min = 2, max = 50)
    private String username;
    private Integer gender;
    private Integer profileType;
    private Integer orientation;
    private boolean online;


    // Credit fields
    private Long creditId;
    @Column(unique = true)
    private Double profileCredit;  //X
    private Integer creditMode;
    private Integer creditCheck;
private Double creditTotal;

/**
 * set the profile derived data
 * @param profile
 */
public void setProfile(final Profile profile){
    this.setProfileId(profile.getId());
    this.setUsername(profile.getUsername());
    this.setGender(profile.getGender());
    this.setProfileType(profile.getProfileType());
    this.setOrientation(profile.getOrientation());
    this.setOnline(profile.isOnline());
}

/**
 * Set the credit aspect
 * @param credit
 */
public void setCredit(final CreditDTO credit){
    this.setCreditId(credit.getId());
    this.setProfileId(credit.getProfileId());
    this.setProfileCredit(credit.getProfileCredit());
    this.setCreditMode(credit.getCreditMode());
    this.setCreditTotal(credit.getCreditTotal());

}

When I don't specify return null; within implementation, the response looks like this. As you can see all objects gets returned which meets condition 1 but where condition 2 is not met empty object fields are returned.

enter image description here


Solution

  • Your "objects" which are elements can't be directly removed from a Page. What you can do is, get the content from the page, that will be a list and then remove the the element from the list according to your condition , then create a new Page with the data fields required for a Page.

    Instead of

        @Override
    public Page<ProfileCreditDTO> findProfileBySelectedParameters(String username, Integer gender, Integer profileType, Integer orientation, Boolean online, Double profileCredit, Integer creditMode, Double creditTotal, Pageable pageable) {
        Page<Profile> searchData= profileRepository.findByAllParameters(username, gender, profileType, orientation, online, pageable);
        Page<ProfileCreditDTO> searchProfileData=null;
        if(searchData != null)
            searchProfileData = searchData.map(x -> this.convertProfileToProfileCreditDTO(x, profileCredit, creditMode, creditTotal));
        return searchProfileData;
    }
    

    try

       @Override
    public Page<ProfileCreditDTO> findProfileBySelectedParameters(String username, Integer gender, Integer profileType, Integer orientation, Boolean online, Double profileCredit, Integer creditMode, Double creditTotal, Pageable pageable) {
        Page<Profile> searchData= profileRepository.findByAllParameters(username, gender, profileType, orientation, online, pageable);
        Page<ProfileCreditDTO> searchProfileData=null;
        if(searchData != null)
            searchProfileData = searchData.map(x -> this.convertProfileToProfileCreditDTO(x, profileCredit, creditMode, creditTotal));
    
        List modifiedAppList = searchProfileData.getContent().stream().filter(v -> v !=null).collect(Collectors.toList()); //Will filter your search result and put it into a list
    
        Page<ProfileCreditDTO> filteredList = new PageImpl<>(modifiedAppList, new PageRequest(0, searchProfileData.getSize()), searchProfileData.getTotalElements()); //Will put your filtered list back into page
    
        return  filteredList; //Returns filtered result
    
    }
    

    Got the answer for this question from Spring Data Rest - How to remove an element from a Page? only amended the code and bit of the wording, as answer was already spot on ;)