Java Can';刷新后,在Hibernate会话之外看不到更改
我将Spring3.1.2与Hibernate4一起使用 我有一个用Java Can';刷新后,在Hibernate会话之外看不到更改,java,spring,hibernate,flush,Java,Spring,Hibernate,Flush,我将Spring3.1.2与Hibernate4一起使用 我有一个用@Repository注释的DAO实现类MyDaoImpl,以便启用异常转换。我有一个服务类MyService,用@Transactional注释如下: public class MyDaoImpl implements MyDao { private SessionFactory sessionFactory; @Autowired public void setSessionFactory(Ses
@Repository
注释的DAO实现类MyDaoImpl
,以便启用异常转换。我有一个服务类MyService
,用@Transactional
注释如下:
public class MyDaoImpl implements MyDao {
private SessionFactory sessionFactory;
@Autowired
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Override
public void saveA(A a)
{
this.sessionFactory.getCurrentSession().saveOrUpdate(a);
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:beans.xml" })
@Transactional
public class MyDaoImplTest implements IMyDaoImplTest {
private MyDao myDao;
private SessionFactory sessionFactory;
@Autowired
public void setMyDao(MyDao myDao)
{
this.myDao = myDao;
}
@Autowired
public void setSessionFactory(SessionFactory sessionFactory)
{
this.sessionFactory = sessionFactory;
}
@Test
@Override
public void testCreateA()
{
A a = new A("A1");
this.myDao.saveA(a);
this.sessionFactory.getCurrentSession().flush();
IDataSet databaseDataSet = this.getConnection().createDataSet();
ITable actualTable = databaseDataSet.getTable("Applications");
IDataSet expectedDataSet = new FlatXmlDataSetBuilder().build(this.getClass().getClassLoader().getResourceAsStream("test-data/applications/savenew.xml"));
ITable expectedTable = expectedDataSet.getTable("Applications");
Assertion.assertEquals(expectedTable, actualTable);
}
}
我编写了一个单元测试类MyDaoImplTest
,如下所示:
public class MyDaoImpl implements MyDao {
private SessionFactory sessionFactory;
@Autowired
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Override
public void saveA(A a)
{
this.sessionFactory.getCurrentSession().saveOrUpdate(a);
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:beans.xml" })
@Transactional
public class MyDaoImplTest implements IMyDaoImplTest {
private MyDao myDao;
private SessionFactory sessionFactory;
@Autowired
public void setMyDao(MyDao myDao)
{
this.myDao = myDao;
}
@Autowired
public void setSessionFactory(SessionFactory sessionFactory)
{
this.sessionFactory = sessionFactory;
}
@Test
@Override
public void testCreateA()
{
A a = new A("A1");
this.myDao.saveA(a);
this.sessionFactory.getCurrentSession().flush();
IDataSet databaseDataSet = this.getConnection().createDataSet();
ITable actualTable = databaseDataSet.getTable("Applications");
IDataSet expectedDataSet = new FlatXmlDataSetBuilder().build(this.getClass().getClassLoader().getResourceAsStream("test-data/applications/savenew.xml"));
ITable expectedTable = expectedDataSet.getTable("Applications");
Assertion.assertEquals(expectedTable, actualTable);
}
}
根据Spring文档,我在更改后刷新会话以避免误报。问题是,刷新后,如果我在Hibernate之外访问DB(例如使用DBUnit),我看不到更改,因此我的断言总是失败
我的配置有什么问题?这是预期的行为。刷新与事务提交是不同的概念。只有在提交后才能看到事务外部的更改。如果要在事务提交后检查数据库的状态,有两个选项:
- 签入带有
注释的方法。此方法将在@posterTransaction
测试方法定义的事务结束后由Spring JUnit runner执行。不要忘记禁用自动事务回滚@Tranactional
)。如果您需要对不同的测试方法进行不同的检查,您可以执行以下操作:(@TransactionConfiguration(defaultRollback=false)
private Runnable check; @AfterTransaction public void performCheck() { if (check != null) check.run(); } @Test @Override public void testCreateA() { ... // Code being tested check = new Runnable() { public void run() { ... // Code to check the state } }; }
- 在测试方法中使用编程事务划分:
private TransactionTemplate tx; @Autowired private void setTransactionManager(PlatformTransactionManager ptm) { tx = new TransactionTemplate(ptm); } @Test @Override @Transactional(progrgation = Propagation.NOT_SUPPORTED) // Disable declarative transaction public void testCreateA() { tx.execute(...); // Code to test tx.execute(...); // Check }
或者,如果您的目标是使用DbUnit检查Hibernate刷新的结果,则可以在同一事务中执行,例如,使用
sessionFactory.getCurrentSession().doWork(…)
谢谢您的回答。那么,我测试刀的方式有什么问题?通过这种方式,我看不到更改,因此无法测试我的DAO。您的测试将需要在同一会话/事务中检索数据。@DanMatthews问如何在同一会话/事务中使用DBUnit?DBUnit直接与数据库通信。