测试Hibernate@Check约束时,java无法生成约束冲突异常
我正在使用Hibernate@Check
注释,但是当约束不满足时,不能让我的测试失败。目前只使用H2数据库的默认Spring引导配置
我错过了什么?在save(..)
之后是否应该有某种刷新
运行测试时,我看到正确创建的表。如果我从日志中复制创建行并使用它创建一个表到我的“real”Postgres数据库中,我可以测试不同的插入,并查看这一行是否受约束
实体
@Getter @Setter
@Entity @Check(constraints = "a IS NOT NULL OR b IS NOT NULL")
public class Constrained {
@Id @GeneratedValue
private Long id;
private String a, b;
}
测试
@DataJpaTest
@RunWith(SpringRunner.class)
public class HibernateCheckTest {
@Resource // this repo is just some boiler plate code but attached at
// the bottom of question
private ConstrainedRepository repo;
@Test @Transactional // also tried without @Transactional
public void test() {
Constrained c = new Constrained();
repo.save(c); // Am I wrong to expect some constraint exception here?
}
}
运行测试时的表生成脚本
create table constrained (id bigint not null, a varchar(255), b varchar(255), primary key (id), check (a IS NOT NULL OR b IS NOT NULL))
存储库(在回购协议中看不到多少,只是为了展示它):
public interface ConstrainedRepository
extends CrudRepository<Constrained, Long> {
}
但是
如果我使用EntityManager
so添加到我的测试类:
@PersistenceContext
private EntityManager em;
然后像这样做:
em.persist(c);
em.flush();
我将得到异常,而不是repo.save(c)
和
用repo.save(c)
更仔细地研究原始测试的日志显示:
org.springframework.test.context.transaction.TransactionContext:139 - Rolled back transaction for test:
...
testException = [null],
因此,出于某种原因,这个错误只是包装和记录。在使用存储库进行持久化时,如何将其“展开”并抛出
# 1 楼答案
多亏了codemonkey的answer,我找到了一个解决方案。通过添加以下内容解决此问题:
去我的测试班
# 2 楼答案
在
ConstrainedRepository
中,扩展JpaRepository
而不是CrudRepository
,然后使用:而不是:
检查是在数据库中强制执行的,只有当更改(在本例中是INSERT语句)刷新到数据库时才会发生
在没有显式刷新的情况下,Hibernate will defer将语句发送到数据库,直到提交事务或执行查询为止
然而,从Spring DataJpaTest文档中:
因此,在这种情况下,没有提交。事务被回滚,语句永远不会刷新到数据库,因此永远不会引发异常