如何测试使用 Hibernate Search 的服务?

Mir*_*dak 2 lucene spring hibernate transactions hibernate-search

我有 JUnit4 测试类,用此方法以及其他方法进行注释:@Transactional

@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);
}
Run Code Online (Sandbox Code Playgroud)

基本上,我正在构建一些发现功能,我想在开发时(主要是稍后)对其进行正确测试。关键是,这个测试总是失败,就好像索引根本没有建立一样。该方法在内存数据库中prepareArtworksForListing()创建(使用persist(..))一些记录。HSqlDbHibernate 与 H.Search/Lucene 正确连接,因为当我用 注释此方法并@Transactional(propagation = Propagation.NOT_SUPPORTED)显式调用em.getTransaction().begin()和时em.getTransaction().commit()/.rollback(),测试通过,但随后的测试方法失败并显示READ_ONLY TX Error,就好像@Transactional该类缺少原始属性一样。

Mir*_*dak 5

我找到了一个解决方案,并且我意识到 Lucene/Hibernate 搜索如何与自动更新索引结合使用。索引在事务提交时(内部)更新,但不是直接更新,而是在flush(). 因此,调用flush()onEntityManager可以在保持@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);
    }
}
Run Code Online (Sandbox Code Playgroud)