这里是有关您的行为的更多详细信息。
根据JPA 2规范(第102页)
如果validate方法返回的ConstraintViolation对象集不为空,则持久性提供程序必须抛出javax.validation.ConstraintViolationException,其中包含对返回的ConstraintViolation对象集的引用,并且必须将事务标记为回滚。
并从hibernate文档
如果发现一个实体无效,则ConstraintViolationException传播约束违例列表,该约束公开了ConstraintViolations集。
当在提交时发生违规时,此异常包装在RollbackException中。否则,[由Hibernate
Validator]返回ConstraintViolationException(例如,在调用flush()时)。
此外,从jpa 2规格开始(第101页)
默认情况下,默认Bean验证组(默认组)将在持久化和更新前生命周期验证事件时进行验证
将所有这些放在一起,我几乎不会感到困惑,因为在我看来,HibernatePersistenceProvider的行为不遵循JPA 2规范,因为:
- 验证必须在“ pre-presist”上执行
- 持久性提供者 必须抛出 ConstraintViolationException
显然,在您的情况下,调用(以及使用HibernatePersistenceProvider时)
ConstraintViolationException不会引发
persist。
因此,根据我的理解并回答您的问题:
- eclipselink是正确的
- hibernate是错误的
(注意:我希望其他人可以确认或不同意我的分析)
重要编辑
我对自己的结论感到困惑。因此,我尝试重现OP描述的行为,但无法立即重现此行为。
我所做的与OP描述的内容非常相似:
- 建立一个小项目,一个实体与一个
@NotNull
字段。 @NotNull
在一个简单的测试中,尝试对字段为null的实例执行persist()。- 断言该
persist()
*** 作将javax.validation.ConstraintViolationException
+标记为事务rollback only
- 使用eclipselink作为持久性提供程序时执行此 *** 作->成功
- 使用hibernate作为持久性提供程序时执行此 *** 作->成功
我的测试与描述OP的测试之间的主要区别是id生成。在成功的测试中,我使用了一个简单的
@GeneratedValue。
将ID生成策略更改为:
@GeneratedValue(strategy = GenerationType.TABLE, generator = "NAME_MUST_NOT_BE_NULL_ID_GENERATOR")@TableGenerator(name = "NAME_MUST_NOT_BE_NULL_ID_GENERATOR", pkColumnValue = "NAME_MUST_NOT_BE_NULL_ID")
我发现了OP描述的确切行为:
- 一个
javax.validation.ConstraintViolationException
被抛出persist()
使用的Eclipselink时。 persist()
使用hibernate时不会抛出任何异常。
因此,当使用Hibernate +时
strategy = GenerationType.TABLE:行为是不同的。我很确定它没有遵循JPA2规范。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)