Alternatives to null-check validations in Java

Daniel Domingueti
2 min readJan 31, 2023

In order to avoid NullPointerExceptions and unexpected code behaviors, developers often need to validate the existence of a value that comes from the database..

//DATABASE EXAMPLE

Investment investment = investmentRepository.findByIdAnd...(id);

if (investment == null) {
throw new NotFoundException("Investment was not found.");
}

//proceeds with the implementation

..or from a request body

//REQUEST BODY EXAMPLE

@PostMapping
public ResponseEntity<InvestmentResponseDTO> insert(@Valid @RequestBody InvestmentRequestDTO investmentRequestDto) {

if (investmentRequestDto.getCategory() != null) {
//proceeds with the implementation
}

//proceeds with the implementation
}

However it’s generally a bad programming practice to perform null checks on parameters once this can lead to maintenance and readability difficulties.

Luckly there’re a few different ways to perform the same validation in a more concise, readable form. Let’s take a look at them.

You’ve probably seen the Optional<T> class when you were fetching some data through native JPA repository methods, such as the most known findById() method.

Optional<T> is a container object that may or may not contain a non-null value. If a value is present, isPresent() will return true and get() will return the value.

With this in mind, whenever you’re going to fetch data from the Repository through native or customized Optional<T> methods, you can ensure the returned value is present through isPresent() and get it through get().

//DATABASE EXAMPLE

Optional<Investment> investment = investmentRepository.findById(id);

if (!investment.isPresent()) {
throw new NotFoundException("Investment was not found.");
}

//proceeds with the implementation

Last but not least, one of the ways to deal with this validation within the request body scope is through NotNull, NotBlank, NotEmpty and Size annotations.

//REQUEST BODY EXAMPLE

@Getter @Setter
public class InvestmentRequestDTO implements Serializable {
private static final long serialVersionUID = 1L;

@NotBlank(message = "Investment type is required")
private String

@NotNull(message = "Investment industry ID is required")
private Long investmentIndustryId;

//proceeds with the implementation

}

Overall, I strongly recommend paying attention to these little details while you’re coding. Overtime the code structure will remain organized and you won’t struggle to make changes in the code.

Thank you’all for your attention in this matter.

Feel free to follow me on Linkedin and Github.

--

--