带hibernate的JUnit:这个实例还没有作为行存在于数据库中



我正在用JUnit做一个测试。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:com/mt/sm/application-context.xml", "classpath:com/mt/sm/security-context.xml"})
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
@Transactional
public class LocationPathServiceImplTest { /* Class code here */ }

测试方法声明非常简单:

@Test
public void testRefresh() { /* Method body */}

我已经在setup()中创建了保存对象并保存到db。而在@Test中,我从DAO运行refresh() (refresh()方法只是调用EntityManager .refresh()),但它导致我下面的错误

org.hibernate.HibernateException: this instance does not yet exist as a row in the database
javax.persistence.PersistenceException: org.hibernate.HibernateException: this instance does not yet exist as a row in the database

我不知道如何修理它。有人以前见过这个吗?如有任何建议,我将不胜感激。

在任何时候,我都不会向数据库提交更改,也不会调用.flush()。据我所知,它们在当前交易范围内。

如果没有更多的代码,我想说,您需要flush您的DAO,以便实例得到持久化。refresh只是对象级别,而flush在数据库级别上执行实际事务(因此rollback = true在测试后回滚)

我不确定其他答案说你应该flush()是正确的,因为这不会向数据库提交任何东西。请参阅Hibernate文档。刷新会话只是获取当前会话中的数据与数据库中的数据同步。所以你的异常是有意义的,如果你没有调用myobject.save()在你的setUp()方法。

我不认为你想在任何地方调用commit(),因为你想在测试完成后回滚一切。在你的类

上使用这些注释
@RunWith(SpringJUnit4ClassRunner.class)
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true) 
@Transactional

你可以在你的setUp()方法上添加@before,尽管如果你的类扩展了TestCase,这将是相同的。Thor84no是正确的,因为@before方法将在与@Test方法相同的事务中执行。如果你真的想用提交的数据在数据库中播种,你可以使用一个带@beforeTransaction注释的方法。

[编辑]

根据你更新的问题,听起来你没有调用persist()或类似的对象,你说你已经在setup()中创建,它被认为是分离的(即不坚持到你的事务中的数据库)。

我还会刷新/关闭/重新打开会话,以强制实际写入数据库。

最新更新