【发布时间】: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