簡體   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