Getting DbUnit for working with sleep mode transaction

I had a problem trying to make changes to a Hibernate transaction in a database so that DbUnit would work correctly in my test case. It seems that DbUnit does not see the changes made by Hibernate because they are not committed at the end of the transaction ... and I'm not sure how to restructure my test case to make this work.

Here is my overly simplified test case to demonstrate my problem: -

@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 overlayType count", 5, actualTable.getRowCount()); DataSourceUtils.releaseConnection(connection.getConnection(), dataSource); } } 

My whole idea of ​​using DbUnit is as follows: -

  • A call to someService.save(...) , which stores the data in several tables.
  • Use DbUnit to get the expected table from XML.
  • Use DbUnit to get the actual table from the database.
  • Make Assertion.assertEquals(expectedTable, actualTable); .

But at the moment, I cannot get DbUnit to see the changes made by Hibernate in the transaction.

How do I change to make DbUnit work with a Hibernate transaction?

Thanks.

+6
source share
2 answers

I have never worked with DbUnit, but it seems TransactionAwareDataSourceProxy will do the trick. Basically you need to wrap the source data source with this proxy server and use it instead so this code:

 new DatabaseConnection(dataSource.getConnection()) 

really goes through the proxy server and uses the same transaction and connection as Hibernate.

I found a data source matching the transaction (use dbunit and hibernate in spring) which reports this.

Another approach would be to abandon transactional tests altogether and manually clear the database. Check out my transactional transactions that are considered artclean malware .

+9
source

It looks like this test case requires two transactions: one to put data into the database, and the second to get it.

What would I do:

  • Use the memory database to clear data when the unit test ends.
  • Remove transactional annotations and directly use the beginTransaction and commit methods of the session.

The initial overlaytype counter will be 0, and after saving the session, it should be 1.

0
source

Source: https://habr.com/ru/post/904247/


All Articles