【问题标题】:How to validate before saving and throw checked exception如何在保存和抛出检查异常之前进行验证
【发布时间】:2019-07-24 12:29:37
【问题描述】:

我有以下场景:

  • 有一个用户存储库可以保存/更新用户
  • 我想在保存/更新之前验证用户的名字/姓氏(执行一些字符串操作)
  • 如果用户的名字/姓氏在执行操作后小于 2 个字符,则应抛出已检查的自定义 UnacceptableStringValueException

请注意,许多服务访问用户存储库,因此在保存之前直接实现新逻辑很麻烦。

为了在保存/更新之前执行验证而不必为每个保存/更新调用显式实现此验证,我尝试做的是使用 JPA 侦听器。使用@PrePersist@PreUpdate 我实现了在每次保存/更新之前执行验证的目标。 但是这个解决方案有两个问题:

  • 检查的异常不会在保存/更新用户的方法上强制执行,异常会通过侦听器自动包装为RuntimeException
  • 当尝试使用 AOP 来捕获所说的 RuntimeException 并解压缩原始检查异常时,我不断收到 org.springframework.transaction.UnexpectedRollbackException: Transaction silently rolled back because it has been marked as rollback-only

请注意,在保存/更新用户之前执行检查的简单服务层不会解决我的用例,因为有一个用户角色存储库也可以保存/更新用户 (@ManyToOne(optional = false, cascade = CascadeType.PERSIST))

解决上面场景中描述的约束的好方法是什么?

【问题讨论】:

  • 您可以使用 java 功能和控制器/服务层中的 if else 条件检查/验证字段值。并使用自定义异常类抛出特定消息。参考(stackoverflow.com/questions/56832667/…
  • 为什么不简单地在实体字段上使用 Bean 验证呢?它与 JPA 很好地集成在一起,无论何时保存/更新实体,无论采用何种方法
  • @crizzis 验证应该在执行字符串操作(例如修剪)之后进行
  • Bean 验证与 pre persist 回调在同一时间被调用
  • @crizzis 感谢您的提示,不幸的是我需要从配置文件中动态加载允许的大小,我不知道这是否与 bean 验证兼容

标签: java hibernate spring-boot jpa


【解决方案1】:

通过修复org.springframework.transaction.UnexpectedRollbackException: Transaction silently rolled back because it has been marked as rollback-only 错误,我找到了一个可行的解决方案。

问题是,检查异常导致意外回滚,为了解决这个问题,我将自定义检查异常添加到可以像这样回滚的异常中:@Transactional(rollbackFor = {UnacceptableStringValueException.class})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-21
    • 2013-06-29
    • 2019-06-19
    • 1970-01-01
    • 2013-04-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多