Hello everyone I am using Spring Boot with MySQL. I have the following error when I try to find information,
javax.persistence.NonUniqueResultException: query did not return a unique result: 2
In my Repository class I have the following code,
Optional findByIdOrEmail(Integer id, String email);
I think the error is because findByIdOrEmail
fetching multiple records because of the OR
operator.
So I used a List
to fetch the values and following is my code, and my goal is to throw an exception that is specifically showing the each duplicate values.
List<User> userList = userRepo.findByIdOrEmail(user.getId(), user.getEmail());
// There will be maximum of 2 records fetched by id and email and I didn't
check if each result is the users record
if (!userList.isEmpty() && userList.size() > 1)
throw new CustomException("Duplicate Record Found" +
" id: " + user.getId() + " and email: " + user.getEmail());
else if (!userList.isEmpty())
throw new CustomException("Duplicate Record Found" +
(userList.get(0).getId().equals(user.getId()) ? "id: " + user.getId() : "email: " + user.getEmail()));
So I was wondering if this approach is the best or are there any other best practices? Because the user should be able to update his/her record but check duplicates with existing other records. And since it is giving a list of values sometimes so I have to check them in a loop. That thing is I haven't done in the above code. So is there another best way or a simple way to do this without looping and multiple if conditions? Highly appreciate any answers. Thanks in advance.
Lets make a custom ResourceAlreadyExistsException class . It will extends the RuntimeException class, and you can add as many parameters to it as you like. I've kept it concise like this.
public class ResourceAlreadyExistsException extends RuntimeException {
public ResourceAlreadyExistsException(String property, String value) {
super(String.format(
"Resource with property %s and value %s already exists." +
"Make sure to insert a unique value for %s",
property, value, property));
}
}
Whenever I need to check for a unique resource, I can tell the user which specific property has what value that causes the error. Furthermore, I notify the user what action must be taken to avoid the error.
Say, I chose to use error *** for my ResourceAlreadyExistsException. Still, I need to hook up this error message to the ExceptionResponseHandler. The extra method is very similar to the method that we usually create for handling all exceptions. In fact, you can easily copy-paste this method for all the exceptions you have. All you have to do, is changing the Exception class to your exception and change the HttpStatus..
@ExceptionHandler(ResourceAlreadyExistsException.class) public final ResponseEntity<ExceptionResponse> handleResourceAlreadyExistsException( ResourceAlreadyExistsException ex, WebRequest req) { ExceptionResponse exceptionResponse = new ExceptionResponse( new Date(), ex.getMessage(), req.getDescription(false) ); return new ResponseEntity<>(exceptionResponse, HttpStatus.UNPROCESSABLE_ENTITY);