简体   繁体   中英

Hibernate Search doesn't reindex lucene index after insert

I'm using Hibernate (with JPA) and Hibernate Search for my Spring web application. 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. According to Hibernate documentation; 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.

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) . 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. 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. 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. Among others, Hibernate Search merges parallel index updates in more efficient combined batch IO operations. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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