1

で使用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を使用して)DBにアクセスすると、変更が表示されないため、アサートが常に失敗することです。

私の設定の何が問題になっていますか?

4

2 に答える 2

3

これは予期される動作です。フラッシュは、トランザクションのコミットとは異なる概念です。コミット後にのみ、トランザクションの外部で変更を確認できます。

于 2012-08-28T11:01:37.990 に答える
0

トランザクションのコミット後にデータベースの状態を確認する場合は、次の2つのオプションがあります。

  • で注釈が付けられたメソッドでチェックインを実行し@AfterTransactionます。@Tranactionalこのメソッドは、テストメソッドで定義されたトランザクションの終了後にSpringJUnitランナーによって実行されます。自動トランザクションロールバックを無効にすることを忘れないでください(@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(...)

于 2012-08-28T11:41:03.137 に答える