【发布时间】:2019-01-24 19:41:32
【问题描述】:
最近,我加入了一个使用 Hibernate Search 的项目。
我怀疑我们的应用程序存在故障,由于在 2 个地方使用了 FullTextEntityManager,导致其他后台作业忽略了新索引的数据:
1) 从UI执行目标数据的搜索时,我们在第一次搜索请求时使用MassIndexer对数据进行索引,所有后续搜索请求都不会导致重新索引:
private final AtomicBoolean initialized = new AtomicBoolean(false);
...
public FullTextQuery buildTransactionSearchQuery(SearchRequestDTO request) {
final FullTextEntityManager fullTextEntityManager = getFullTextEntityManager();
final Query expression = buildTransactionSearchExpression(request.getFilter(), fullTextEntityManager);
final FullTextQuery query = fullTextEntityManager.createFullTextQuery(expression, Transaction.class);
return query;
}
...
private FullTextEntityManager getFullTextEntityManager() {
final FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
if (initialized.get()) {
return fullTextEntityManager;
} else {
synchronized (initialized) {
if (!initialized.getAndSet(true)) {
try {
fullTextEntityManager.createIndexer().startAndWait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
return fullTextEntityManager;
}
}
}
2) 在后台作业中:
@Scheduled(initialDelay = 1_000, fixedDelay = 5_000)
private void indexAuditValues() {
Instant previousRunTime = ...; // assume data is set
Instant currentTime = ...;
int page = 0;
boolean hasMore = true;
while (hasMore) {
hasMore = hsIndexingService.indexAuditValues(previousRunTime, currentTime, page++);
}
}
@Transactional(readOnly = true)
public boolean indexAuditValues(Instant previousRunTime, Instant currentTime, int page) {
PageRequest pageRequest = return new PageRequest(page, batchSize, Sort.Direction.ASC, AUDIT_VALUE_SORT_COLUMN);
Page<AuditValue> pageResults = auditValueRepository.findByAuditTransactionLastModifiedDateBetween(previousRunTime, currentTime, pageRequest);
FullTextEntityManager fullTextEntityManager = getFullTextEntityManager();
List<AuditValue> content = pageResults.getContent();
content.forEach(fullTextEntityManager::index); // here we do index the data
return pageResults.hasNext();
}
private FullTextEntityManager getFullTextEntityManager() {
return Search.getFullTextEntityManager(entityManager);
}
最近我们的用户反映新数据没有出现在搜索页面上,可能是因为在两个不同步的单独线程中使用了2个FullTextEntityManagers?如果是,如何解决?
我们使用文件 Spring boot、Hibernate Search、Lucene,并在文件系统中存储索引。
实体标注@Indexed,可搜索字段标注@Field。
【问题讨论】:
标签: spring lucene hibernate-search