2011-12-21 3 views
6

DbUnit이 테스트 케이스에서 제대로 작동하기 위해 Hibernate 트랜잭션 내에서 변경된 사항을 데이터베이스로 푸시하는 데 문제가 있습니다. DbUnit은 트랜잭션이 끝날 때 커밋되지 않았기 때문에 Hibernate가 변경 한 사항을 보지 못하고있는 것 같습니다. 그리고 이것을 작동시키기 위해 테스트 케이스를 어떻게 재구성해야할지 모르겠습니다.DbUnit에서 최대 절전 모드 트랜잭션 사용하기

여기 내 문제를 보여주기 위해 내 이상 - 단순화 된 테스트 케이스의 : - DbUnit을 사용에

@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); 
    } 
} 

내 모든 생각은에 - 여러 테이블에 데이터를 저장

  • 전화 someService.save(...).
  • XML에서 예상 테이블을 가져 오려면 DbUnit을 사용하십시오.
  • 데이터베이스에서 실제 테이블을 가져 오려면 DbUnit을 사용하십시오.
  • Do Assertion.assertEquals(expectedTable, actualTable);.

그러나이 시점에서 나는 트랜잭션 내에서 Hibernate에 의해 만들어진 변경 사항을 DbUnit에 표시 할 수 없습니다.

DbUnit이 Hibernate 트랜잭션으로 잘 작동하도록 어떻게 변경해야합니까?

감사합니다.

답변

9

나는 DbUnit을 함께 일한 적이해야하지만, 그것은 트릭을 할 것입니다 TransactionAwareDataSourceProxy처럼 보인다. 기본적으로이 프록시 원래 데이터 소스를 포장해야하고이 코드 있도록 대신 사용 :

new DatabaseConnection(dataSource.getConnection()) 

실제로 프록시를 통해 이동과 같은 트랜잭션 및 최대 절전 모드와 같은 연결을 사용합니다.

나는 이것을 설명하는 Transaction aware datasource (use dbunit & hibernate in spring) 블로그 게시물을 발견했습니다.

또 다른 방법은 트랜잭션 테스트를 건너 뛰고 대신 수동으로 데이터베이스를 정리하는 것입니다. 내 transactional tests considered harmful artcle을 확인하십시오.

+0

+1 좋은 답변 Tomasz! – Nilesh

0

테스트 케이스에는 데이터베이스에 데이터를 넣는 것과 두 번째 트랜잭션을 검색하는 두 가지 트랜잭션이 필요합니다.

는 내가 뭘 할 것은 : 단위 테스트가 종료 될 때 데이터가 정리되도록

  • 는 메모리 데이터베이스를 사용합니다.
  • 트랜잭션 주석을 제거하고 세션의 beginTransaction 및 commit 메소드를 직접 사용하십시오.

초기 overlaytype 카운트가 0이 될 것이고, 세션을 저장 한 후에는 1

관련 문제