如何测试使用Hibernate Search的服务? [英] How to test services that use 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屋!