Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hibernate搜索返回过期数据_Hibernate_Jpa_Hibernate Search - Fatal编程技术网

Hibernate搜索返回过期数据

Hibernate搜索返回过期数据,hibernate,jpa,hibernate-search,Hibernate,Jpa,Hibernate Search,我正在使用JPARepository创建和更新我的实体。 这两种方法都是通过save()方法实现的。 当我创建实体时,使用Hibernate搜索可以很好地进行搜索,但当我更新实体时,奇怪的事情开始发生 在某种意义上,更新被识别出来,即只找到与搜索实际匹配的更新数据,但它仍然返回包含旧数据的实体。使用JPAs findAll返回实体的更新版本 例如: 苹果通过save()更新为现在的香蕉。 我现在可以通过hibernate搜索查询搜索香蕉,它会找到一个名为apple的实体 重新启动服务器后,问题得

我正在使用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)