Reputation: 1
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
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