【发布时间】:2019-08-01 06:18:44
【问题描述】:
我在 Spring Boot 中有一个模型,对字段有正则表达式约束
@Entity(name = "foo")
public class Foo {
//primary key id and other fields
@Pattern(regexp="^[0-9]{10}", message="length must be 10")
@Column(name = "mobile_number", nullable = false)
private String mobileNumber;
}
我还有一个异常处理程序
@Order(Ordered.HIGHEST_PRECEDENCE)
@ControllerAdvice
public class RestExceptionHandler extends ResponseEntityExceptionHandler {
// other exception handlers
@ExceptionHandler(javax.validation.ConstraintViolationException.class)
protected ResponseEntity<Object> handleConstraintViolation(javax.validation.ConstraintViolationException ex) {
ApiError apiError = new ApiError(HttpStatus.BAD_REQUEST);
apiError.setMessage("Validation Error");
apiError.addValidationErrors(ex.getConstraintViolations());
return buildResponseEntity(apiError);
}
}
现在,当我使用不正确的手机号码模式创建 Foo 的新实例时,ConstraintViolationException 被抛出,我收到消息 Validation Error。但是,当我尝试使用不正确的手机号码更新 Foo 的现有实例时,不会触发此异常。相反,我收到以下错误:
11:28:30.357 [http-nio-8080-exec-6] ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction] with root cause
javax.validation.ConstraintViolationException: Validation failed for classes [com.example.app.model.Foo] during update time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
ConstraintViolationImpl{interpolatedMessage='length must be 10', propertyPath=mobileNumber, rootBeanClass=class com.example.app.model.Foo, messageTemplate='length must be 10'}
]
at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:140)
at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreUpdate(BeanValidationEventListener.java:88)
at org.hibernate.action.internal.EntityUpdateAction.preUpdate(EntityUpdateAction.java:248)
at org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:119)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:478)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:356)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1454)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:511)
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3283)
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2479)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:473)
为什么它在创建时起作用但在更新时不起作用?我们是否需要添加一些配置来检查约束违规以进行更新?另外,如何让消息“长度必须为 10”而不是“验证错误”显示?我似乎无法通过handleConstraintViolation 方法访问@Pattern 中定义的消息。
【问题讨论】:
标签: java spring-boot exception constraints