如何测试使用Hibernate Search的服务? [英] How to test services that use Hibernate Search?

查看:77
本文介绍了如何测试使用Hibernate Search的服务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有JUnit4测试类,该类带有@Transactional 并带有其他方法:

I have JUnit4 test class, annotated with @Transactional with this method in it, along with other methods:

@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(..))在HSqlDb内存数据库中创建一些记录. Hibernate正确连接了H.Search/Lucene,因为当我用@Transactional(propagation = Propagation.NOT_SUPPORTED)注释此方法并显式调用em.getTransaction().begin()em.getTransaction().commit()/.rollback()时,通过了测试,但是随后的测试方法因READ_ONLY TX Error失败,就像该类没有原始的@Transactional属性.

Basically, I'm building some discovery functionality and I would like to test it properly while developing and mainly later. The point is, this test always fails, as if the index was not built at all. The method prepareArtworksForListing() creates (using persist(..)) some records in HSqlDb in-memory database. Hibernate is wired with H.Search/Lucene properly, because when I annotate this method with @Transactional(propagation = Propagation.NOT_SUPPORTED) and explicitly call em.getTransaction().begin() and em.getTransaction().commit()/.rollback(), the test is passed, BUT THEN subsequent test methods fail with READ_ONLY TX Error, as if the original @Transactional attribute was absent for the class.

推荐答案

我找到了一个解决方案,并且意识到,Lucene/Hibernate Search如何与自动更新索引结合使用.索引在事务提交时(内部)更新,但不是直接更新,而是在flush()上更新.因此,在EntityManager上调用flush()可以达到目的,同时使该类的@Transactional保持完整.

I've found a solution and I've realized, how does Lucene/Hibernate Search works in connection with auto-updating indexes. The indexes are updated (internally) on transaction commit, but not directly, but on flush(). Therefore, calling flush() on EntityManager does the trick while keeping @Transactional intact for the class.

所以代码应该看起来像这样(我还添加了一些异常处理):

So the code should look something like this (I've added some exception handling as well):

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

这篇关于如何测试使用Hibernate Search的服务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆