Как проверить сервисы, которые используют 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);
    }
}
Другие вопросы по тегам