简体   繁体   English

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

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

I'm using Hibernate (with JPA) and Hibernate Search for my Spring web application. 我将Hibernate(与JPA一起)和Hibernate Search用于Spring Web应用程序。 When the application starts on the server, I create the Indexes with the following code: 当应用程序在服务器上启动时,我使用以下代码创建索引:

EntityManager em = emf.createEntityManager();

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

em.close();

That works like a charm. 就像魅力一样。 However, when I insert new entities through Hibernate, the indexes aren't getting modified to contain the new entities. 但是,当我通过Hibernate插入新实体时,索引不会被修改为包含新实体。 According to Hibernate documentation; 根据Hibernate文档; this should happen automatically. 这应该自动发生。

This is how I insert an entity: 这是我插入实体的方式:

    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;
    }

And this is how I use Hibernate Search: 这就是我使用休眠搜索的方式:

    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;

When I insert the account, It's not searchable (indexed) before I restart the application. 当我插入帐户时,在重新启动应用程序之前无法搜索(建立索引)。 As I said, the configuration is made with JPA annotations. 如我所说,该配置是通过JPA注释进行的。

Is there something I'm missing here? 我在这里想念什么吗?

As it turns out, the solution to this answer was quite simple. 事实证明,此答案的解决方案非常简单。 In the example above, I was saving an account, and tried to search it afterwards, by some properties on an related entity (User) . 在上面的示例中,我正在保存一个帐户,然后尝试通过相关实体(User)上的某些属性对其进行搜索。 When you persist an object with related entities that is included in one of your queries, you need to do: 当您保留其中一个查询中包含的具有相关实体的对象时,您需要执行以下操作:

em.refresh(account)

after you persist it. 坚持下去之后。 Otherwise the related entities' indexes won't be rebuilt, and hence you won't be able to find your new entity by the realted entities' properties. 否则,将不会重建相关实体的索引,因此您将无法通过所获取的实体的属性来找到新实体。

Hibernate Search will apply the updates to the index on commit of the transaction. 提交事务后,Hibernate Search会将更新应用于索引。 In your example you're running a search just after having stored the entity, but before having committed; 在您的示例中,您是在存储实体之后但在提交之前就运行搜索; you should test the query in a follow up transaction, which is what you would need in most cases in practice. 您应该在后续交易中测试查询,这在大多数情况下是实际需要的。

Since that might sound odd, an explanation seem in order: one reason for this design choice is that Lucene is non transactional, so if we were to apply the changes before the commit, other threads would see the changes already in the index but unable to load the entities. 由于这听起来可能很奇怪,所以按顺序进行了解释:进行这种设计选择的一个原因是Lucene是非事务性的,因此,如果我们在提交之前应用更改,其他线程将看到索引中已经存在的更改,但无法加载实体。 It would also be impossible to guarantee a proper revert on a transaction rollback/abort/crash. 保证交易回滚/中止/崩溃的正确还原也是不可能的。

Updating a Lucene index could be relatively slow so it applies some performance tricks. 更新Lucene索引可能相对较慢,因此应用了一些性能技巧。 Among others, Hibernate Search merges parallel index updates in more efficient combined batch IO operations. 除其他外,Hibernate Search以更有效的组合批处理IO操作合并并行索引更新。 It's not just merging all writes from a same transaction but it's merging all writes from all transactions happening on the same application. 它不仅合并来自同一事务的所有写入,还合并来自同一应用程序上发生的所有事务的所有写入。 In other words, performance would be horrible if it was to apply index writes before the transaction is committed. 换句话说,如果在提交事务之前应用索引写入,则性能将很糟糕。

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

相关问题 Hibernate Search不会索引/重新索引实体 - Hibernate Search doesn't index/reindex entities 相同的Hibernate Search Lucene索引可用于多个应用程序 - Same Hibernate Search Lucene index for multiple applications Lucene索引未使用Hibernate Search和Spring Data更新 - Lucene index not updated with Hibernate Search and Spring Data 通过 Hibernate 搜索浏览/浏览 Lucene 索引 - Explore / browse Lucene index by Hibernate search Spring JPA + Hibernate搜索:如何仅更新搜索索引(Lucene)? - Spring JPA + Hibernate Search : How update the Search Index(Lucene) only? Hibernate 带有枚举字段的搜索/Lucene 范围查询不返回任何结果 - Hibernate Search/Lucene range query with enum field doesn't return any results lucene 索引文件随机崩溃,需要重新索引 - lucene index file randomly crash and need to reindex 如何索引使用Lucene休眠搜索已创建的数据库 - how to index a database already created using lucene hibernate search 如何使用Hibernate Search / Lucene索引取决于列值的行? - How to index rows dependent on column values with Hibernate Search / Lucene? 未创建带有 lucene 搜索索引文件的休眠:IndexWriterConfig.setWriteLockTimeout(J)Lorg/apache/lucene/index/IndexWriterConfig; - hibernate with lucene search index files are not created: IndexWriterConfig.setWriteLockTimeout(J)Lorg/apache/lucene/index/IndexWriterConfig;
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM