2014-04-16 2 views
1

나는 JUnit4 테스트 클래스, 다른 방법과 함께, 거기에이 방법으로 @Transactional로 주석 한 :Hibernate Search를 사용하는 서비스를 테스트하는 방법은 무엇입니까?

@Test 
public void testDiscoverArtworksByTitle() 
{ 
    FullTextEntityManager ftem = Search.getFullTextEntityManager(this.entityManager); 

    this.prepareArtworksForListing(); 
    ftem.flushToIndexes(); 

    List<ArtworkListItem> listItems = this.artworkService.discoverArtworksByTitle("Die Hard"); 
    Assert.assertNotEquals("There are some items in the list", 0, listItems.size()); 

    // housekeeping 
    ftem.purgeAll(ArtworkEntity.class); 
} 

는 기본적으로, 나는 몇 가지 검색 기능을 구축하고있어 개발하는 동안 내가 제대로 테스트 할 것 그리고 주로 나중에. 요컨대,이 테스트는 항상 색인이 작성되지 않은 것처럼 실패합니다. prepareArtworksForListing() 메서드는 메모리 내 데이터베이스에 일부 레코드를 (persist(..)을 사용하여) 만듭니다. Hethernate는 H.Search/Lucene과 적절하게 연결되어 있는데,이 메소드에 @Transactional(propagation = Propagation.NOT_SUPPORTED)이라는 주석을 달고 명시 적으로 em.getTransaction().begin()em.getTransaction().commit()/.rollback()을 호출하면 테스트가 통과되지만 이후의 테스트 메소드는 READ_ONLY TX Error으로 실패합니다. 원래 @Transactional 속성이없는 경우입니다. 수업.

답변

3

나는 해결책을 발견했고, Lucene/Hibernate Search가 자동 업데이트 색인과 어떻게 관련되는지 깨달았다. 인덱스는 트랜잭션 커밋에서 (내부적으로) 업데이트되지만 직접 적용되지는 않지만 flush()에 업데이트됩니다. 따라서 flush()EntityManager으로 호출하면 @Transactional을 그대로 유지하면서 속임수를 사용합니다.

@Test 
public void testDiscoverArtworksByTitle() 
{ 
    FullTextEntityManager ftem = Search.getFullTextEntityManager(this.entityManager); 

    this.prepareArtworksForListing(); 
    this.entityManager.flush(); // <-- ADDED FLUSH() CALL 
    ftem.flushToIndexes(); 

    try 
    { 
     List<ArtworkListItem> listItems = this.artworkService.discoverArtworksByTitle("Die Hard"); 
     Assert.assertNotEquals("There are some items in the list", 0, listItems.size()); 
    } 
    finally 
    { 
     // housekeeping 
     ftem.purgeAll(ArtworkEntity.class); 
    } 
} 
:

그래서 코드는 다음과 같이 (나뿐만 아니라 처리 일부 예외를 추가 한)를 찾아야한다

관련 문제