我有 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);
}
基本上,我正在构建一些发现功能,我想在开发时(主要是稍后)对其进行正确测试。
关键是,这个测试总是失败,就好像索引根本没有建立一样。
方法prepareArtworksForListing()
在 persist(..)
中创建(使用 HSqlDb
)一些记录内存数据库。 Hibernate 与 H.Search/Lucene 正确连接,因为当我用 @Transactional(propagation = Propagation.NOT_SUPPORTED)
注释此方法时并显式调用 em.getTransaction().begin()
和em.getTransaction().commit()/.rollback()
,测试通过,但随后的测试方法失败,并显示 READ_ONLY TX Error
,就像原来的 @Transactional
该类缺少属性。
最佳答案
我找到了一个解决方案,并且我意识到 Lucene/Hibernate 搜索如何与自动更新索引结合使用。索引在事务提交时(内部)更新,但不是直接更新,而是在 flush()
上更新。因此,在 EntityManager
上调用 flush()
可以达到目的,同时保持类的 @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);
}
}
关于spring - 如何测试使用 Hibernate Search 的服务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23121764/