【问题标题】:ConstraintViolationException doesn't work for both DTO & MODEL classes at the same timeConstraintViolationException 不能同时对 DTO 和 MODEL 类起作用
【发布时间】:2020-05-20 10:47:48
【问题描述】:

我在 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 不为空白时,我会得到一个新的Spring 控制台中的 ConstraintViolationException 和 Postman 中的 Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction 用于密码字段,即使处理了异常。

【问题讨论】:

  • BaseModel 是什么样的? id 字段是否有任何限制?你能添加一个更大的堆栈跟踪吗?你也有独特的专栏电子邮件。你用的是什么数据库?可能是电子邮件的多个空值是不允许的。
  • 它只包含一个 ID 字段。
  • 如果您可以在保存之前调试检查 UserModel(我假设它是通过 BaseModel 扩展的实体)实例的值。查看实例的值是否符合模型上设置的限制(电子邮件是唯一的,密码、名字和姓氏不为空)
  • 问题在于,一旦它通过控制器方法的@Valid 验证,它就不再适用于来自 MODEL 类的验证并引发一些回滚异常。我的猜测是我需要使用@Transactional,但它也没有用。

标签: java spring spring-boot validation


【解决方案1】:

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

选项:

  1. RollbackException 创建一个异常处理程序。 (真的很笼统,没有信息)
  2. RollbackException 创建一个异常处理程序并检查原因。 (更好一点,但更复杂和肮脏)
  3. 在保存之前创建一个带有@Valid UserModel 签名的图层

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-03
    • 1970-01-01
    • 2018-01-09
    • 1970-01-01
    • 1970-01-01
    • 2019-06-24
    • 1970-01-01
    • 2020-08-18
    相关资源
    最近更新 更多