一尘不染

使DbUnit与Hibernate事务一起使用

hibernate

我在尝试将Hibernate事务中所做的更改推送到数据库以使DbUnit在我的测试用例中正常工作时遇到问题。似乎DbUnit没有看到Hibernate所做的更改,因为它们尚未在事务结束时提交。

这是我过度简化的测试用例,用于演示我的问题:-

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
        "classpath:applicationContext-test.xml"
})
@TransactionConfiguration(transactionManager = "transactionManager")
@Transactional
public class SomeTest {
    @Autowired
    protected DataSource dataSource;

    @Autowired
    private SessionFactory sessionFactory;

    @Test
    public void testThis() throws Exception {
        Session session = sessionFactory.getCurrentSession();

        assertEquals("initial overlayType count", 4, session.createQuery("from OverlayType").list().size());

        //-----------
        // Imagine this block is an API call, ex: someService.save("AAA");
        // But for the sake of simplicity, I do it this way
        OverlayType overlayType = new OverlayType();
        overlayType.setName("AAA");
        session.save(overlayType);
        //-----------

        // flush has no effect here
        session.flush();

        assertEquals("new overlayType count", 5, session.createQuery("from OverlayType").list().size());

        // pull the data from database using dbunit
        IDatabaseConnection connection = new DatabaseConnection(dataSource.getConnection());
        connection.getConfig().setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new MySqlDataTypeFactory());
        QueryDataSet partialDataSet = new QueryDataSet(connection);
        partialDataSet.addTable("resultSet", "select * from overlayType");
        ITable actualTable = partialDataSet.getTable("resultSet");

        // FAIL: Actual row count is 4 instead of 5
        assertEquals("dbunit's overlayType count", 5, actualTable.getRowCount());

        DataSourceUtils.releaseConnection(connection.getConnection(), dataSource);
    }
}

我使用DbUnit的整个想法是:

  • someService.save(...)将数据保存到多个表的调用。
  • 使用DbUnit从XML获取期望的表。
  • 使用DbUnit从数据库获取实际表。
  • Assertion.assertEquals(expectedTable, actualTable);

但是,在这一点上,我无法让DbUnit看到Hibernate在事务中所做的更改。

我应该如何更改以使DbUnit与Hibernate事务正常工作?

谢谢。


阅读 262

收藏
2020-06-20

共1个答案

一尘不染

我从未使用过DbUnit,但似乎TransactionAwareDataSourceProxy可以解决问题。基本上,您需要使用此代理包装原始数据源,并改用它,以便此代码:

new DatabaseConnection(dataSource.getConnection())

实际上通过代理,并使用与Hibernate相同的事务和连接。

我找到了说明
事务的数据源(在spring使用dbunit和hibernate)
博客文章。

另一种方法是完全跳过事务测试,而手动清除数据库。看看我的交易测试是否有害

2020-06-20