【发布时间】:2017-04-28 10:44:42
【问题描述】:
假设我有带有属性的机场实体:
@Column(nullable = false, unique = true)
private final String code;
显然,当我使用之前使用的代码持久化实体时,它会抛出 DataIntegrityViolationException
我有启用 Spring Data REST 的 Spring Boot 应用程序。
对于这种情况,有RepositoryRestExceptionHandler处理DataIntegrityViolationExceptions并将其映射到409状态码:
@ExceptionHandler({ OptimisticLockingFailureException.class, DataIntegrityViolationException.class })
ResponseEntity<ExceptionMessage> handleConflict(Exception o_O) {
return errorResponse(HttpStatus.CONFLICT, new HttpHeaders(), o_O);
}
典型响应如下所示:
HTTP/1.1 409
X-Application-Context: application
Content-Type: application/hal+json;charset=UTF-8
Transfer-Encoding: chunked
Date: Fri, 28 Apr 2017 10:21:31 GMT
{
"cause" : {
"cause" : {
"cause" : null,
"message" : "Unique index or primary key violation: \"UK_X9RMMVEVTW274QQXGT73OQ74_INDEX_C ON PUBLIC.AIRPORT(CODE) VALUES ('null', 54)\"; SQL statement:\ninsert into AIRPORT (id, rec_version, code, description) values (null, ?, ?, ?) [23505-194]"
},
"message" : "could not execute statement"
},
"message" : "could not execute statement; SQL [n/a]; constraint [\"UK_X9RMMVEVTW274QQXGT73OQ74_INDEX_C ON PUBLIC.AIRPORT(CODE) VALUES ('null', 54)\"; SQL statement:\ninsert into AIRPORT (id, rec_version, code, description) values (null, ?, ?, ?) [23505-194]]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement"
}
问题是使用 SQL 异常来响应响应是否是一种好方法。在我看来不是。
如果没有,有哪些好的做法可以遵循以及如何在引导和数据 REST 中实现它们?
【问题讨论】:
-
正确的解决方案是在通过 Spring Validator 实现或通过自定义 JSR303 注释进入数据库之前应用您自己的验证。
-
在这种情况下,验证逻辑必须进行数据库查找以查看具有给定代码的机场是否已经存在。这是好方法吗?性能明智?基于此评论,不推荐使用 JSR303:github.com/spring-projects/spring-boot/issues/…
-
除了数据库查找之外,您还打算怎么做呢。您不能让它在 DB 提交时失败,因为这不会让您产生 有意义 错误消息:没有客户端会希望看到您的 SQL 异常。
标签: spring-boot spring-data-rest