我正在使用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()
中创建了保存obj并保存到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()。为了我的理解,它们属于当前的交易范围。
答案 0 :(得分:2)
如果没有更多代码我会说,你需要flush
你的DAO,所以实例会被持久化。 refresh
只是对象级别,而flush
在数据库级别执行实际事务(因此rollback = true
因此在测试后回滚)
答案 1 :(得分:1)
我不确定其他答案是否应该flush()
是正确的,因为这不会对数据库提交任何内容。见Hibernate docs。刷新会话只会使当前在会话中的数据与数据库中的数据同步。因此,如果您没有在setUp()方法中调用myobject.save()
,那么您的异常就有意义了。
我认为您不想在任何地方调用commit()
,因为您希望在测试完成后回滚所有内容。在班级
@RunWith(SpringJUnit4ClassRunner.class)
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
@Transactional
然后,您可以在setUp()方法中添加@before
,但如果您的类扩展了TestCase,那么它将是相同的。 Thor84no是正确的,因为@before方法将在与@Test方法相同的事务中执行。如果您确实希望使用提交的数据为数据库设定种子,则可以使用注释为@beforeTransaction
的方法。
[编辑]
根据您更新的问题,听起来您没有在您在setup()中创建的对象上调用persist()
或类似内容,并且它被认为已被删除(即不会持久保存到您的数据库中)交易)。
答案 2 :(得分:0)
我还会刷新/关闭/重新打开会话以强制实际写入数据库。