What is the best way to handle errors when using Spring's Jpa Repository deleteById(Long id) method?
By default the deleteById(), checks to see if the ID has an existing row in the database, if it doesn't it throws a org.springframework.dao.EmptyResultDataAccessException because it expects a row size of 1.
I first tried to use my Exception Handler to pick up on this exception, which worked fine but the message exposes my package and class name to the user when Spring returns the error message.
@ExceptionHandler(EmptyResultDataAccessException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
protected ResponseEntity<RestApiError> handleEmptyResultDataAccessException(EmptyResultDataAccessException ex, HttpServletRequest request) {
RestApiError error = new RestApiError(HttpStatus.BAD_REQUEST, Map.of("message", ex.getMessage()), request.getRequestURI());
return new ResponseEntity<>(error, error.getHttpStatus());
}
ex.getMessage() returns:
No class net.demo.customerservice.model.CustomerLocation entity with id 7 exists!
Instead I decided to catch EmptyResultDataAccessException, and then throw more useful exception and message where I call deleteById();
My current code:
public void delete(Long id) {
try {
repository.deleteById(id); // call Spring's Data JPA repository method deleteById
} catch (EmptyResultDataAccessException ex) {
throw new EntityNotFoundException("Location with ID: [" + id + "] was not found");
}
}
This works great, and returns a good error message to the user but it seems like a hack.
Is there any better way to handle the EmptyResultDataAccessException? I could also use the existsById() method before calling the delete method, but then I am using two queries.