JPA和Bean验证的独特约束
-
29-09-2019 - |
题
我想有一个 @Unique
bean验证的约束,但这不是标准提供的。如果我要使用JPA @UniqueConstraint
我不会有唯一的验证和错误报告机制。
有没有办法定义 @Unique
作为Bean验证约束并将其与JPA结合在一起,因此JPA创建具有唯一约束的列,并检查值是否唯一?
解决方案
除非您在整个桌子上获得锁, ,基本上不可能使用SQL查询(任何并发事务都可以在手动检查后,但在正在进行的交易提交之前修改数据)。换句话说,不可能在Java级别实施有效的唯一验证,从而提供验证实现。唯一的可靠方法是在进行交易时。
BV规格总结了这样的总结:
附录D. Java持久性2.0集成
问题:我们是否应该添加@unique将映射到@column(unique = true)?
@Unique不能可靠地在Java级别进行测试,但可以生成数据库唯一的约束生成。 @Unique今天不属于BV规格。
因此,尽管我同意在豆验证异常中包含唯一(和非零)约束违规行为是很好的,但目前并非如此。
参考
- 豆验证规范(JSR 303)
- 有关验证和持续约束的问题
其他提示
有关如何实现@unique及其周围问题的更多信息,请参见此处 - http://community.jboss.org/wiki/accessinghibernatesessionwithinaconstraintvalidator
好吧,您可以做到,但这并不小。问题是:验证器需要数据库访问以执行一些查询以检查,是否已经插入的值已经存在。而且这是从验证器中真正完成的,因为它无法访问SessionFactory/Session。当然,您可以在验证器内实例化(会话/sessionFactory),但这不是一个好的编码实践。
您可以使验证器阅读JPA注释并应用它。这是一个使用弹簧验证器的示例,可以用作扩展的想法。
您也可以注射(@Inject
或春天 @Autowired
)您的会话bean在自定义验证器中,并且容器应知道如何将其连接起来。我只知道这是一个春天的例子:
import javax.validation.ConstraintValidator;
public class MyConstraintValidator implements ConstraintValidator {
@Autowired //@Inject
private Foo aDependency;
...
}