我正在Spring 3.1.2
使用Hibernate 4
。
我有一个用MyDaoImpl
注释的DAO实现类@Repository
,以便启用异常转换。我的服务类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);
}
}
我写了一个单元测试类MyDaoImplTest
,如下所示:
@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之外访问数据库(例如使用DBUnit),我看不到更改,所以我的断言总是失败。
我的配置有什么问题?
答案 0 :(得分:3)
这是预期的行为。 Flush是与事务提交不同的概念。只有在提交后才能看到事务之外的更改。
答案 1 :(得分:0)
如果要在事务提交后检查数据库的状态,则有两个选项:
检查用@AfterTransaction
注释的方法。在@Tranactional
测试方法定义的事务结束后,Spring JUnit运行程序将执行此方法。不要忘记禁用自动事务回滚(@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 flush的结果,则可以在同一事务中执行此操作,例如,使用sessionFactory.getCurrentSession().doWork(...)
。