我有一个junit测试来检查我的唯一性约束是否正常工作。我发现在添加重复条目后,为了得到我预期的异常,我需要 进行数据库查询或在测试中设置@Rollback(false)。 (我猜这是由于某种懒惰的提交逻辑?)
这是预期的吗?或者有更好的方法来编写这个测试用例吗?
@Test
@Rollback(false) // without this no duplicate is found. Documentation and test1() don't accord with this. Why?
public void addDuplExchange() {
exception.expect(DataIntegrityViolationException.class); //org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint ["UK_CI07R484MKOOCNBAD6Q6HG1DB_INDEX_2 ON PUBLIC.EXCHANGES(EXCHANGE_NAME_LOWERCASE) VALUES ('exchange3', 1)"; SQL statement:
System.out.println("add dupl exchange...");
ExchangeDbo e3a1 = dbService.addNewExchange("Exchange3");
System.out.println(e3a1);
ExchangeDbo e3a2 = dbService.addNewExchange("eXcHanGe3"); // this should fail
System.out.println(e3a2);
// List<ExchangeDbo> x = dbService.getAllExchanges();
// x.forEach(System.out::println);
}
答案 0 :(得分:1)
这是预期的吗?
绝对。
我假设dbService.addNewExchange()
调用repository.save()
(内部调用entityManager.persist()
)。这只会使新创建的实体托管,这意味着JPA现在将跟踪其状态。必要时,此实体的状态将刷新到db ,不迟于事务提交。
我需要进行数据库查询或在测试中设置@Rollback(false)
默认情况下,Hibernate在事务提交和查询之前执行flush。后者是为了确保到目前为止对实体所做的更改反映在查询结果中。
要使测试失败,请切换到repository.saveAndFlush()
,立即强制刷新,或者通过向测试中注入EntityManager
并在两次调用后调用EntityManager.flush()
来明确刷新上下文dbService.addNewExchange()
已经制作完成。