Hibernate搜索返回过期数据
我正在使用JPARepository创建和更新我的实体。 这两种方法都是通过save()方法实现的。 当我创建实体时,使用Hibernate搜索可以很好地进行搜索,但当我更新实体时,奇怪的事情开始发生 在某种意义上,更新被识别出来,即只找到与搜索实际匹配的更新数据,但它仍然返回包含旧数据的实体。使用JPAs findAll返回实体的更新版本 例如: 苹果通过save()更新为现在的香蕉。 我现在可以通过hibernate搜索查询搜索香蕉,它会找到一个名为apple的实体 重新启动服务器后,问题得到解决 我这里有什么问题 编辑一些代码以进行澄清:Hibernate搜索返回过期数据,hibernate,jpa,hibernate-search,Hibernate,Jpa,Hibernate Search,我正在使用JPARepository创建和更新我的实体。 这两种方法都是通过save()方法实现的。 当我创建实体时,使用Hibernate搜索可以很好地进行搜索,但当我更新实体时,奇怪的事情开始发生 在某种意义上,更新被识别出来,即只找到与搜索实际匹配的更新数据,但它仍然返回包含旧数据的实体。使用JPAs findAll返回实体的更新版本 例如: 苹果通过save()更新为现在的香蕉。 我现在可以通过hibernate搜索查询搜索香蕉,它会找到一个名为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
}
休眠搜索
@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();
}
}
@Transactional
公共列表搜索CustomerByFirstNamePhase(字符串文本){
FullTextEntityManager FullTextEntityManager=Search.getFullTextEntityManager(entityManager);
Query Query=fullTextEntityManager
.getSearchFactory()
.buildQueryBuilder()
.forEntity(客户类)
.overridesForField(“名字”、“Edengram_查询”)
.overridesForField(“lastName”、“edengram\u查询”)
.get()
.SimpleQuery字符串()
.onFields(“名字”、“姓氏”)
.WithAndAndDefaultOperator()
.匹配(文本)
.createQuery();
List results=getJpaQuery(query.getResultList();
返回结果;
}
//第一步
私有QueryBuilder getQueryBuilder(){
FullTextEntityManager FullTextEntityManager=Search.getFullTextEntityManager(entityManager);
返回fullTextEntityManager.getSearchFactory()
.buildQueryBuilder()
.forEntity(客户类)
.get();
}
//步骤3
私有FullTextQuery getJpaQuery(org.apache.lucene.search.Query luceneQuery){
FullTextEntityManager FullTextEntityManager=Search.getFullTextEntityManager(entityManager);
返回fullTextEntityManager.createFullTextQuery(luceneQuery,Customer.class);
}
public void initSearchIndex(){
entityManager=entityManager.GetEntityManager工厂().createEntityManager();
FullTextEntityManager FullTextEntityManager
=Search.getFullTextEntityManager(entityManager);
试一试{
fullTextEntityManager.createIndexer().startAndWait();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
JPARep
@Repository
public interface CustomerRepository extends JpaRepository<Customer, Long> {}
@存储库
公共接口CustomerRepository扩展了JpaRepository{}
我解决了这个问题,没有像下面那样自己创建实体管理器
entityManager = entityManager.getEntityManagerFactory().createEntityManager();
我改为使用实体管理器,它是自动连接的。
这个函数不是在构造函数中完全创建的,因此initSearchIndex()会抛出一个错误。等待第一个搜索请求到达,然后调用initSearchIndex()一次就可以了。这听起来像是缓存问题。是否为搜索的实体启用了二级缓存?看起来好像查询结果是使用缓存的valueshow来具体化的,我会检查这个吗?实体类中未设置缓存注释是否启用了二级缓存(通过将hibernate属性中的
hibernate.cache.use_second_level_cache
或spring.jpa.properties.hibernate.cache.use_second_level_cache
设置为true
)?如果是,请尝试禁用它并重新运行测试。如果不是,那么这是另一个问题,因为它根本没有设置,所以我假设它默认为false。是否要成功检查保存实体?实体a=a存储。保存(a)