Java 单元测试在标记为@Transactional时通过,但在未标记为@Transactional时失败
设置JUNIT测试Java 单元测试在标记为@Transactional时通过,但在未标记为@Transactional时失败,java,spring,hibernate,jpa,junit,Java,Spring,Hibernate,Jpa,Junit,设置JUNIT测试 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({ "/applicationContext.xml", "/applicationContext-security.xml" }) @TransactionConfiguration(defaultRollback = true) @Transactional public class BlahIntegrationTests{ @Test pu
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({ "/applicationContext.xml", "/applicationContext-security.xml" })
@TransactionConfiguration(defaultRollback = true)
@Transactional
public class BlahIntegrationTests{
@Test
public void testMappingsOfHugeObjectGraph(){
}
}
我试图测试我的hibernate映射(注释驱动的和基于JPA的)是否正确,并且当运行时,我的测试通过(只是断言创建了一个ID)
如果我把@Transactional
拿走,我的一些关系就会出现我所期望的错误。有没有人想过,当它是@事务性的时,为什么它没有失败
编辑:为了澄清,抛出的异常是关于错误的hibernate映射(这是一个非常大的对象结构,我已经删除了其中一些)保存对象时如果删除@Transactional,则Hibernate工厂将在其等效的自动提交模式下运行,在该模式下,您进行的每个新访问都会生成一个完整的新会话。因此,一旦您检索到一个对象,它将立即不再与打开的会话关联,并且不符合延迟加载的条件。如果您删除@Transactional,您的测试数据库将不会在另一个测试中为空,因此测试不会被隔离
若你们有它,那个么一些测试可能会通过,即使它们应该失败(如你们所描述的,或者另一个例子是若你们插入了一个重复了一些唯一约束的实体)
解决方案是将@Transactional放在适当的位置并注入
@PersistenceContext
private EntityManager em;
在从数据库中提取数据之前,请执行以下操作
em.flush();
em.clear();
第一行将导致会话和数据库之间的同步(提供者通常等到事务结束)。
第二行将从会话中删除所有实体,以便所有查询都将转到数据库
在测试之后,所有内容都会回滚,因此您的数据库处于原始状态
希望能有所帮助。是的,但我遇到的问题是保存时映射不正确。我将补充我的问题。这确实是需要发生的冲水。具体的问题是在我的许多表中的几百列中,我知道我有一些typeo等,我正在使用单元测试来修复它们。现在我有了一个dao.flush(),它可以正确地找到错误。