我在DTO和MODEL类上都有一些验证注释:

DTO:

public class UserDto {
  private Long id;

  @NotBlank
  private String firstName;

  @NotBlank
  private String lastName;

  private String email;

}


和模型:

public class UserModel extends BaseModel<Long> {

  @NotBlank
  private String firstName;

  @NotBlank
  private String lastName;

  @Column(unique = true)
  private String email;

  @NotBlank
  private String password;
}


我想测试这种方法:

@PutMapping("/update")
public DTO update(@Valid @RequestBody UserDTO dto) {
    return baseFacade.saveOrUpdate(dto);
}


我创建了一个@ControllerAdvice注释类:

@ExceptionHandler(ConstraintViolationException.class)
public ResponseEntity<CustomExceptionResponse> handleConstraintViolationException(ConstraintViolationException exception) {

    //initialize the CustomExceptionResponse here...
    return new ResponseEntity<>(exceptionResponse, HttpStatus.BAD_REQUEST);

}


如果我尝试使用带有空白firstName字段的DTO更新用户,则处理程序将按预期工作,但是当lastNamefirstName不为空时,我将得到一个新的ConstraintViolationException在Spring控制台中,在Postman中为密码字段输入Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction,即使已处理异常。

最佳答案

保存期间会抛出您的异常。如果您具有@Transactional,则默认逻辑是在存在RunTimeException时回滚。然后,您看到的ContraintViolationException被包裹在RollbackException原因中。这是在定义ExceptionHandler触发之前完成的。

选项:


RollbackException创建一个异常处理程序。 (实际上是一般性的,没有提供信息)
RollbackException创建一个异常处理程序并检查原因。 (好一点,但更复杂和肮脏)
保存前创建带有@Valid UserModel签名的图层

09-04 08:06