2014-05-08 54 views
1

執行帶自動索引的批量插入時Hibernate Search創建了數以萬計的org.apache.lucene.document.Field實例,這些實例都保留在內存中,直到事務完成。Hibernate搜索:在批量插入時防止內存使用量過大

由於我沒有設法解決任何HS選項,我不想flushToIndexes未完成的交易,我想暫停自動索引編號,然後手動更新索引。對於我設置以下選項:

hibernateProperties.put("hibernate.search.default.indexBase", "path/to/index"); 
hibernateProperties.put("hibernate.search.model_mapping", searchMappingFactory.createSearchMapping()); 
hibernateProperties.put("hibernate.search.autoregister_listeners", false); 

,我編寫自定義FullTextIndexEventListener用類似的方法:

@Override 
public void onPostInsert(PostInsertEvent event) { 
    if (!isPaused) { 
     super.onPostDelete(event); 
    } 
} 

我整合,使用我的自定義積分:

@Component 
public class HibernateEventIntegrator { 

    @Autowired 
    private SessionFactoryImpl sessionFactory; 
    @Autowired 
    private SearchIndexEventListener searchIndexEventListener; 

    @PostConstruct 
    public void integrate() { 
     EventListenerRegistry listenerRegistry = sessionFactory.getServiceRegistry().getService(EventListenerRegistry.class); 
     listenerRegistry.appendListeners(EventType.POST_INSERT, searchIndexEventListener); 
     //... and so for all events like in HibernateSearchIntegrator 
     searchIndexEventListener.initialize(sessionFactory.getProperties()); 
    } 
} 

然而,在這種不會讀取大小寫映射,就好像沒有實體被編入索引一樣,它們只能由本機HS集成商看到。

我也嘗試使用攔截器跳過動作,但它似乎並不是最好的解決方案。

是否有解決方案可以通過編程方式暫停自動索引而不完全切換到手動索引?

回答

1

我們解決了定製TransactionalWorker的問題,使其刷新並在給定的操作次數後以這種方式釋放內存。這就是我希望worker.batch_size做,下面的代碼:

public class TransactionalFlushingWorker extends TransactionalWorker { 

private static final int INDEX_BATCH_SIZE = 2000; 

private final AtomicInteger indexingWithoutFlushCounter = new AtomicInteger(); 

public void performWork(Work<?> work, TransactionContext transactionContext) { 
    super.performWork(work, transactionContext); 
    if (indexingWithoutFlushCounter.incrementAndGet() > INDEX_BATCH_SIZE) { 
     flushWorks(transactionContext); 
    } 
} 

public void flushWorks(TransactionContext transactionContext) { 
    indexingWithoutFlushCounter.set(0); 
    super.flushWorks(transactionContext); 
} 
} 

登記:

hibernateProperties.put("hibernate.search.worker.scope", TransactionalFlushingWorker.class.getName());