user13412844
user13412844

Reputation: 1

Lucene Hibernate Search

Im trying to implement a lucene search. I built the Repo as the following public class CustomizedContentItemRepositoryImpl implements CustomizedContentItemRepository {

@PersistenceContext
private EntityManager entityManager;

@Override
public List<ContentItem> librarySearch(String searchText) {

    SearchResult<ContentItem> result = Search.session(entityManager).search(ContentItem.class)
            .where(f -> f.match()
                    .fields("description", "title", "creator.firstName", "creator.lastName")
                    .matching(searchText))
            .fetchAll();
    List<ContentItem> contentItems = result.hits();
    return contentItems;
}

and also the service Impl as the flowing:

public List<ContentItem> searchContentItems(String searchText) {
    return contentItemRepository.librarySearch(searchText);
}

when i test it im getting always a null value

here is a test code @Test void searchContentItems() throws InterruptedException { ContentItem video1 = createContentItem(ContentType.VIDEO); contentItemRepository.save(video1);

    ContentItem video2 = createContentItem(ContentType.VIDEO, 1000);
    video2.getSubjects().clear();
    contentItemRepository.save(video2);

    ContentItem audio = createContentItem(ContentType.AUDIO);
    contentItemRepository.save(audio);
    assertEquals(3, contentItemRepository.findAll().size());

        Search.session(entityManager)
                .massIndexer(ContentItem.class)
                .startAndWait();

    Collection<ContentItem> videos = contentItemService.searchContentItems("type");
    assertEquals(2, videos.size());
    Iterator<ContentItem> iterator = videos.iterator();
    assertEquals(video2.getId(), iterator.next().getId());
    assertEquals(video1.getId(), iterator.next().getId());
}

Upvotes: 0

Views: 168

Answers (1)

yrodiere
yrodiere

Reputation: 9977

Are you getting a null value, or just an empty list? Most likely you are getting an empty list.

The results you're observing are due to the fact indexing happens when you commit a transaction. From what I can see, your test is not using a transaction, so you're never indexing anything.

Note the mass indexing is not useful either: since your ORM session wasn't even flushed to the database, the mass indexer (which uses its own session) will only see an empty database.

Try to encapsulate the various operations in transaction templates, as explained here:


@Autowired
TransactionTemplate transactionTemplate;

@Test
void searchContentItems() throws InterruptedException {
    transactionTemplate.execute(ignored -> {
        ContentItem video1 = createContentItem(ContentType.VIDEO);
        contentItemRepository.save(video1);

        ContentItem video2 = createContentItem(ContentType.VIDEO, 1000);
        video2.getSubjects().clear();
        contentItemRepository.save(video2);

        ContentItem audio = createContentItem(ContentType.AUDIO);
        contentItemRepository.save(audio);
        return null;
    });

    transactionTemplate.execute(ignored -> {
        assertEquals(3, contentItemRepository.findAll().size());

        Collection<ContentItem> videos = contentItemService.searchContentItems("type");
        assertEquals(2, videos.size());
        Iterator<ContentItem> iterator = videos.iterator();
        assertEquals(video2.getId(), iterator.next().getId());
        assertEquals(video1.getId(), iterator.next().getId());
        return null;
    });
}

In order for this test to pass, you will also need to configure Hibernate Search to wait for indexing to finish before proceeding to the next transaction. You can do that by setting the automatic indexing synchronization strategy to sync.

In src/test/resources/application.properties:

hibernate.search.automatic_indexing.synchronization.strategy = sync

Upvotes: 1

Related Questions