Batch Index using Hibernate Search and Seam
mat Nov 1, 2007 2:12 PMWe need to index a large number of records using Hibernate Search;
Following the documentations and examples from SEAM, we have implemented the followings. This is to eliminate Out Of Memory Exception and Timeout Exception when indexing a large number of records.
The method works fine (well, haven?t tested it with a large number yet) when it is called from a stateful seam component (as the backing bean for use actions).
However, since this would be a long running process we need to add the @Asynchronous. Adding this annotation stops the method after the EntityManager call and log.info("EntityManager initilized."); is never called !
The persistence.xml has been modified for the specified batchSize as per documentation.
Your help and feedback is highly appreciated;
Environment:
JBoss-4.2.1
SEAM-2.0.CR1
RichFaces-3.1.2
@Name("indexManager") public class IndexManagerBean { @Logger static Log log; public int batchSize = 50; //@Asynchronous public void buildIndex(Class entityClass) { log.info("asynchronously rebuilding Lucene index for entity: " + entityClass); EntityManager em = (EntityManager) Component.getInstance("entityManager"); log.info("EntityManager initilized."); FullTextSession fullTextSession = (FullTextSession)em.getDelegate(); fullTextSession.setFlushMode(FlushMode.MANUAL); fullTextSession.setCacheMode(CacheMode.IGNORE); org.hibernate.Transaction transaction = fullTextSession.beginTransaction(); //Scrollable results will avoid loading too many objects in memory ScrollableResults results = fullTextSession.createCriteria( entityClass ).scroll( ScrollMode.FORWARD_ONLY); int index = 0; while( results.next() ) { index++; fullTextSession.index( results.get(0) ); //index each element if (index % batchSize == 0) fullTextSession.clear(); //clear every batchSize since the queue is processed } transaction.commit(); try { if (results != null) results.close(); } catch (Exception ex) { ex.printStackTrace(); } } }
The entityManager is configured in the components.xml as:
<persistence:filter name="accessCompanyFilter"> <persistence:name>accessCompanyFilter</persistence:name> <persistence:parameters> <key>currentAccessCompany</key> <value>#{currentAccessCompany}</value> </persistence:parameters> </persistence:filter> <persistence:managed-persistence-context name="entityManager" auto-create="true" entity-manager-factory="#{TestEntityManagerFactory}" persistence-unit-jndi-name="java:/ TestEntityManagerFactory"> <persistence:filters><value>#{accessCompanyFilter}</value></persistence:filters> </persistence:managed-persistence-context> <persistence:managed-persistence-context name="gloabalEntityManager" auto-create="true" entity-manager-factory="#{TestEntityManagerFactory}" persistence-unit-jndi-name="java:/TestEntityManagerFactory"> </persistence:managed-persistence-context>