如何解决通过不存在的PK删除时如何处理Spring Data JPA删除?
在使用 Spring 的 Jpa Repository deleteById(Long id)
方法时处理错误的最佳方法是什么?
默认情况下,deleteById()
会检查 ID 是否在数据库中存在现有行,如果没有,则抛出 org.springframework.dao.EmptyResultDataAccessException
,因为它期望行大小为 1。>
我首先尝试使用我的异常处理程序来处理这个异常,它工作正常,但是当 Spring 返回错误消息时,该消息向用户公开了我的包和类名。
@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()
返回:
没有类 net.demo.customerservice.model.CustomerLocation 存在 ID 为 7 的实体!
相反,我决定捕获 EmptyResultDataAccessException
,然后在我调用 deleteById()
的地方抛出更多有用的异常和消息;
我当前的代码:
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");
}
}
这很好用,并向用户返回了一个很好的错误消息,但它看起来像一个黑客。
有没有更好的方法来处理 EmptyResultDataAccessException
?我也可以在调用 delete 方法之前使用 existsById()
方法,但随后我使用了两个查询。
解决方法
通常最好避免在整个代码中捕获异常。如果您可以将异常处理委托给另一个类,您就可以在一个地方一致地处理整个应用程序中的错误。您可以为此使用 @ControllerAdvice
:
@ControllerAdvice
class GlobalControllerExceptionHandler {
@ExceptionHandler(EmptyResultDataAccessException.class)
public ResponseEntity<> handleRecordNotFound(EmptyResultDataAccessException ex) {
LOG.trace("Record not found: {}",ex.getMessage());
RestApiError error = new RestApiError(HttpStatus.BAD_REQUEST,Map.of("message","Record not found"),request.getRequestURI());
return new ResponseEntity<>(error,error.getHttpStatus());
}
}
客户端知道它请求删除哪个实体,因此不需要在返回给客户端的错误消息中包含 id。您可以将带有他 id 的消息记录到日志文件中。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。