繁体   English   中英

插入后,Hibernate Search不会重新索引lucene索引

[英]Hibernate Search doesn't reindex lucene index after insert

我将Hibernate(与JPA一起)和Hibernate Search用于Spring Web应用程序。 当应用程序在服务器上启动时,我使用以下代码创建索引:

EntityManager em = emf.createEntityManager();

FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(em);
fullTextEntityManager.createIndexer().startAndWait();

em.close();

就像魅力一样。 但是,当我通过Hibernate插入新实体时,索引不会被修改为包含新实体。 根据Hibernate文档; 这应该自动发生。

这是我插入实体的方式:

    EntityTransaction tx = null;
    EntityManager em = emf.createEntityManager();


    try {
        tx = em.getTransaction();
        tx.begin();

        em.persist(account);
        em.flush();


        tx.commit();
    }
    catch (RuntimeException e) {
        if ( tx != null && tx.isActive() ) tx.rollback();
        return null;
    }

这就是我使用休眠搜索的方式:

    EntityManager em = emf.createEntityManager();



    FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(em);

    em.getTransaction().begin();


    QueryBuilder qb = fullTextEntityManager.getSearchFactory()
            .buildQueryBuilder().forEntity(AccountPojo.class).get();
    org.apache.lucene.search.Query luceneQuery = qb
    .keyword()
    .onFields("id", "user.email", "user.firstName", "user.lastName", "user.phoneNumber", "user.streetAddress")
    .matching(term)
    .createQuery();


    // wrap Lucene query in a javax.persistence.Query
    org.hibernate.search.jpa.FullTextQuery jpaQuery =
                    fullTextEntityManager.createFullTextQuery(luceneQuery, AccountPojo.class);

    jpaQuery.setProjection(FullTextQuery.SCORE, FullTextQuery.THIS, "id", "user.email", "user.firstName", "user.lastName", "user.phoneNumber");

    // execute search
            List result = jpaQuery.getResultList();


            em.getTransaction().commit();
            em.close();

    return result;

当我插入帐户时,在重新启动应用程序之前无法搜索(建立索引)。 如我所说,该配置是通过JPA注释进行的。

我在这里想念什么吗?

事实证明,此答案的解决方案非常简单。 在上面的示例中,我正在保存一个帐户,然后尝试通过相关实体(User)上的某些属性对其进行搜索。 当您保留其中一个查询中包含的具有相关实体的对象时,您需要执行以下操作:

em.refresh(account)

坚持下去之后。 否则,将不会重建相关实体的索引,因此您将无法通过所获取的实体的属性来找到新实体。

提交事务后,Hibernate Search会将更新应用于索引。 在您的示例中,您是在存储实体之后但在提交之前就运行搜索; 您应该在后续交易中测试查询,这在大多数情况下是实际需要的。

由于这听起来可能很奇怪,所以按顺序进行了解释:进行这种设计选择的一个原因是Lucene是非事务性的,因此,如果我们在提交之前应用更改,其他线程将看到索引中已经存在的更改,但无法加载实体。 保证交易回滚/中止/崩溃的正确还原也是不可能的。

更新Lucene索引可能相对较慢,因此应用了一些性能技巧。 除其他外,Hibernate Search以更有效的组合批处理IO操作合并并行索引更新。 它不仅合并来自同一事务的所有写入,还合并来自同一应用程序上发生的所有事务的所有写入。 换句话说,如果在提交事务之前应用索引写入,则性能将很糟糕。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM