3

で使用Spring 3.1.2していHibernate 4ます。

例外変換が有効になるように、MyDaoImpl注釈が付けられたDAO実装クラスがあります。次のように注釈が付けられ@Repositoryたサービスクラスがあります。MyService@Transactional

public class MyService implements IMyService {

    private MyDao myDao;

    @Autowired
    public void setMyDao(MyDao dao) {
       this.myDao = dao;
    }

    @Override
    @Transactional
    public void createA(String name)
    {
        A newA = new A(name);
        this.myDao.saveA(newA);
    }
}

私は次のようにユニットテストクラスMyServiceTestを作成しました。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:beans.xml" })
@Transactional
@TransactionConfiguration(defaultRollback = true)
public class MyServiceTest implements IMyServiceTest {

    private IMyService myService;

    private SessionFactory sessionFactory;

    @Autowired
    public void setMyService(IMyService myService)
    {
        this.myService = myService;
    }

    @Autowired
    public void setSessionFactory(SessionFactory sessionFactory)
    {
        this.sessionFactory = sessionFactory;
    }

    @Test
    @Override
    public void testCreateA()
    {
       //Assume that there is already a row of table A with the name "A1"
       //so I expect to get a Spring DataAccessException (or subtypes) 
       //when the session is flushed
       this.myService.createA("A1");

       this.sessionFactory.getCurrentSession().flush();

       //asserts
    }
}

テストを実行すると、Hibernate固有の例外が発生しConstraintViolationExceptionます。フォーラムで、これは翻訳システムがトランザクションの外部で行われるためであることがわかりました。この場合、testCreateA()返品後です。これが本当の原因かどうかはわかりませんが、本当の場合は、DAOで翻訳が機能するかどうかをテストできないことを意味します。@Transactional1つの解決策は、単体テストから注釈を削除することですが、ロールバック機能のメリットはありません。

あなたの推薦は何ですか?


編集:SessionFactory現在のセッションにアクセスしてフラッシュできるように、コンテキストで宣言されたものをテストクラスに追加しました。

いくつかの追加の説明:この場合、セッションがフラッシュされたときに例外が発生します(これはトランザクション内にあります)。ドキュメントで説明されているように、誤検知を回避するためにセッションをフラッシュします。また、デフォルトの伝播はREQUIREDであるため、testCreateA()トランザクションはへの呼び出しにも使用されます。createA()そのため、変更は(通常)testCreateA()返されるまでフラッシュされません。

4

1 に答える 1

1

PersistenceExceptionTranslationPostProcessorBeanの定義を追加しましたか?好き

   <!--
        Post-processor to perform exception translation on @Repository classes
        (from native exceptions such as JPA PersistenceExceptions to
        Spring's DataAccessException hierarchy).
    -->
    <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

Springdocから。

@Repositoryアノテーションを保持するすべてのBeanに永続性例外変換を自動的に適用PersistenceExceptionTranslationAdvisorし、公開されたプロキシ(既存のAOPプロキシまたはターゲットのすべてのインターフェイスを実装する新しく生成されたプロキシ)に対応するものを追加するBeanポストプロセッサ。

ネイティブリソースの例外をSpringのDataAccessException 階層に変換します。インターフェイスを実装するBeanを自動検出し、 PersistenceExceptionTranslatorその後、候補の例外を変換するように求められます

于 2012-08-27T11:25:55.543 に答える