我正在使用JPARepository来创建和更新我的实体。 两者都通过save()方法。 使用Hibernate Search进行搜索在创建实体时工作正常,但是当我更新它时,奇怪的事情开始发生。
在某种意义上,更新得到识别,只有找到实际匹配搜索的更新数据,但它仍然返回包含旧数据的实体。使用JPA findAll返回实体的更新版本。
一个例子: Apple通过save()更新到现在为banana。 我现在可以通过休眠搜索查询搜索banana,并找到名为apple的实体。
重新启动服务器后问题得以解决。
这可能是我的问题?
编辑一些代码以澄清:
@Entity
@Indexed
@AnalyzerDef(name = "edgeNgram",
tokenizer = @TokenizerDef(factory = WhitespaceTokenizerFactory.class),
filters = {
@TokenFilterDef(factory = ASCIIFoldingFilterFactory.class), // Replace accented characeters by their simpler counterpart (è => e, etc.)
@TokenFilterDef(factory = LowerCaseFilterFactory.class), // Lowercase all characters
@TokenFilterDef(factory = EdgeNGramFilterFactory.class,
params = {
@Parameter(name = "minGramSize", value = "1"),
@Parameter(name = "maxGramSize", value = "10")
}
) // Generate prefix tokens)
})
@AnalyzerDef(name = "edgeNGram_query",
tokenizer = @TokenizerDef(factory = WhitespaceTokenizerFactory.class),
filters = {
@TokenFilterDef(factory = ASCIIFoldingFilterFactory.class), // Replace accented characeters by their simpler counterpart (è => e, etc.)
@TokenFilterDef(factory = LowerCaseFilterFactory.class) // Lowercase all characters
})
public class Customer {
@Column(nullable = false)
@Size(max = 100)
@NotNull
@NotBlank
@Field(analyzer = @Analyzer(definition = "edgeNgram"))
private String firstName;
//more class
}
Hibernate搜索
@Transactional
public List<Customer> searchCustomerByFirstAndLastNamePhrase(String text){
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
Query query = fullTextEntityManager
.getSearchFactory()
.buildQueryBuilder()
.forEntity(Customer.class)
.overridesForField("firstName", "edgeNGram_query")
.overridesForField("lastName","edgeNGram_query")
.get()
.simpleQueryString()
.onFields("firstName","lastName")
.withAndAsDefaultOperator()
.matching(text)
.createQuery();
List<Customer> results = getJpaQuery(query).getResultList();
return results;
}
//step 1
private QueryBuilder getQueryBuilder() {
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
return fullTextEntityManager.getSearchFactory()
.buildQueryBuilder()
.forEntity(Customer.class)
.get();
}
//step 3
private FullTextQuery getJpaQuery(org.apache.lucene.search.Query luceneQuery) {
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
return fullTextEntityManager.createFullTextQuery(luceneQuery, Customer.class);
}
public void initSearchIndex() {
entityManager = entityManager.getEntityManagerFactory().createEntityManager();
FullTextEntityManager fullTextEntityManager
= Search.getFullTextEntityManager(entityManager);
try {
fullTextEntityManager.createIndexer().startAndWait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
JPARep
@Repository
public interface CustomerRepository extends JpaRepository<Customer, Long> {}
答案 0 :(得分:0)
我解决了这个问题,不是自己创建一个实体经理,如下所示。
entityManager = entityManager.getEntityManagerFactory().createEntityManager();
我改为使用自动装配的实体管理器。 这个没有在构造函数中完全创建,因此initSearchIndex()抛出一个错误。等到第一个搜索请求到达然后调用initSearchIndex()一次完美。