Hibernate Search返回过时的数据

时间:2018-05-06 18:39:35

标签: hibernate jpa hibernate-search

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

1 个答案:

答案 0 :(得分:0)

我解决了这个问题,不是自己创建一个实体经理,如下所示。

entityManager = entityManager.getEntityManagerFactory().createEntityManager();

我改为使用自动装配的实体管理器。 这个没有在构造函数中完全创建,因此initSearchIndex()抛出一个错误。等到第一个搜索请求到达然后调用initSearchIndex()一次完美。