Search code examples
springoopnulloption-typenullable

Is there a more innovative way to handle null exceptions in the following cases?


Now I have created a Response for Puppy

@Getter
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@AllArgsConstructor(access = AccessLevel.PUBLIC)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class PuppyResponse {

    private Long puppyId;

    private String name;

    private Integer age;

    private String breed;

    private Long vetId;

    private String vetName;

    public PuppyResponse(Long puppyId, String name, Integer age, String breed) {
        this.puppyId = puppyId;
        this.name = name;
        this.age = age;
        this.breed = breed;
    }

    public static PuppyResponse of(Puppy puppy) {
        Optional<Vet> vet = Optional.ofNullable(puppy.getVet());
        if(vet.isPresent()) {
            return new PuppyResponse(
                    puppy.getPuppyId(),
                    puppy.getName(),
                    puppy.getAge(),
                    puppy.getBreed(),
                    vet.get().getVetId(),
                    vet.get().getName()
            );
        }else {
            return new PuppyResponse(
                    puppy.getPuppyId(),
                    puppy.getName(),
                    puppy.getAge(),
                    puppy.getBreed()
            );
        }
    }

    public static List<PuppyResponse> listOf(List<Puppy> puppies) {
        return puppies.stream()
                .map(PuppyResponse::of)
                .collect(Collectors.toList());
    }
}

It's possible that the dog attribute vet is null. I designed Puppy to use a different constructor depending on whether it's null or not, but this doesn't seem like a good way to do it. Of course it works without problems, but I want to design it in a better way. How do I handle nulls?


Solution

  • If you want to just provide new Veet Object if puppy.getVet() is null by using orElseGet

    Vet vet = Optional.ofNullable(puppy.getVet()).orElseGet(Vet::new);
    

    If you want to provide default Veet Object if puppy.getVet() is null

    Vet vet = Optional.ofNullable(puppy.getVet()).orElseGet(PuppyResponse::getDefaultVet);
    

    This way you don't need to check ifPresent and create responses accordingly

    return new PuppyResponse(
        puppy.getPuppyId(),
        puppy.getName(),
        puppy.getAge(),
        puppy.getBreed(),
        vet.getVetId(),
        vet.getName()
    );
    

    To provide default Vet Object

    private static Vet getDefaultVet(){
        Vet v = new Vet();
        v.setVetId(0);
        v.setName("Default Name");
        return v;
    }