Как проверить сервисы, которые используют 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);
}
По сути, я создаю некоторую функциональность обнаружения, и я хотел бы протестировать ее должным образом при разработке и, главным образом, позже. Дело в том, что этот тест всегда терпит неудачу, как будто индекс не был построен вообще. Метод prepareArtworksForListing()
создает (используя persist(..)
) некоторые записи в HSqlDb
база данных в памяти. Hibernate правильно связан с H.Search/Lucene, потому что когда я аннотирую этот метод с @Transactional(propagation = Propagation.NOT_SUPPORTED)
и явно позвонить em.getTransaction().begin()
а также em.getTransaction().commit()/.rollback()
, тест пройден, НО ЗАТЕМ последующие методы тестирования завершатся неудачно с READ_ONLY TX Error
как будто оригинал @Transactional
атрибут отсутствовал для класса.
1 ответ
Я нашел решение и понял, как работает 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);
}
}