I used Hibernate Search when it first came out. I have come back to it on a project where we are using Java 19 and Hibernate trying to layer in search. The project was created with Springboot 2.7.x.
I made the mistake of trying to make a JpaDataTest and then do some searches. I have gotten to the point now where it should be working but I am seeing this:
HSEARCH000027: Mass indexing is going to index 0 entities.
Probably has something to do with TX, but I put some code into the test to make sure the insertions do get committed.
package com.xumo.features.model;
import org.hibernate.search.engine.search.query.SearchResult;
import org.hibernate.search.mapper.orm.Search;
import org.hibernate.search.mapper.orm.massindexing.MassIndexer;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.transaction.support.TransactionTemplate;
import javax.persistence.EntityManager;
import java.time.Duration;
import java.util.function.Supplier;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.is;
@DataJpaTest
public class ContentSearchTest {
private final Logger log = LoggerFactory.getLogger(ContentSearchTest.class);
@Autowired
private EntityManager entityManager;
@Autowired
private ContentRepository contentRepository;
@Autowired
TransactionTemplate txTemplate;
private <T> T doInTransaction(Supplier<T> operation) {
return txTemplate.execute(status -> operation.get());
}
private void doInTransaction(Runnable operation) {
txTemplate.execute(status -> {
operation.run();
return null;
});
}
@BeforeEach
public void setup() throws InterruptedException {
Movie dirtyHarry = new Movie("Dirty Harry");
Movie magnumForce = new Movie("Magnum Force", "Sequel to dirty harry.", Duration.ofMinutes(103));
Movie fortyEightHours = new Movie("48 Hours");
doInTransaction(() -> {
contentRepository.save(dirtyHarry);
contentRepository.save(magnumForce);
contentRepository.save(fortyEightHours);
entityManager.flush();
});
Search.session(entityManager).massIndexer(Content.class).startAndWait();
}
@Test
public void canSearchContent() {
//List<Content> results = contentRepository.searchBy("Dirty harry", 10, "title", "description");
SearchResult<Content> results = Search.session(entityManager)
.search(Content.class)
.where(f -> f.match().fields("title", "description")
.matching("Dirty Harry ").fuzzy(2))
.fetch(10);
log.info("search result: " + results);
assertThat(contentRepository.findAll().iterator().hasNext(), is(true));
for (Content content : contentRepository.findAll()) {
log.info("found: [" + content.getTitle() + " " + content.getDescription() + "]");
}
assertThat(results.total().hitCount(), greaterThan(0L));
}
}