[hibernate-issues] [Hibernate-JIRA] Commented: (HSEARCH-399) NPE in org.hibernate.search.backend.WorkQueue.clear()

Dobes Vandermeer (JIRA) noreply at atlassian.com
Thu Sep 17 19:21:50 EDT 2009


    [ http://opensource.atlassian.com/projects/hibernate/browse/HSEARCH-399?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=33981#action_33981 ] 

Dobes Vandermeer commented on HSEARCH-399:
------------------------------------------

Hi Sanne,

By moving to a seperate thread I'm referring to the use of these settings:

            <property name="hibernate.search.worker.execution" value="async"/> <!-- sync or async --> 
            <property name="hibernate.search.worker.buffer_queue.max" value="5"/> 
            <property name="hibernate.search.worker.thread_pool.size" value="5"/> 

Whereby hibernate search updates the indexes in a worker thread instead of delaying the connection.

I recognize that stifling the NPE by checking for null might hide another bug, but I also have no suggestions on what that bug would be.  Only something with a thorough understanding of how this system works would be able to understand when and how the WorkQueue would have a null queue but still have clear() called on it.  Perhaps clear() isn't supposed to be called after the work queue is sealed?  Even so, it seems like it IS being called in that case.



> NPE in org.hibernate.search.backend.WorkQueue.clear()
> -----------------------------------------------------
>
>                 Key: HSEARCH-399
>                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HSEARCH-399
>             Project: Hibernate Search
>          Issue Type: Bug
>    Affects Versions: 3.1.1.GA
>            Reporter: Dobes Vandermeer
>
> Our server blew up, and we're seeing a continuous stream of:
> [#|2009-09-17T06:24:02.169-0700|SEVERE|sun-appserver9.1|books.db.search.SafeBatchedQueueingProcessor|_ThreadID=40;_Threa
> dName=httpSSLWorkerThread-8080-19;_RequestID=97e3df6c-2fc7-4f54-a47a-e77ba48d1a07;|RuntimeException during cancelWorks()
> java.lang.NullPointerException
>         at org.hibernate.search.backend.WorkQueue.clear(WorkQueue.java:58)
>         at org.hibernate.search.backend.impl.BatchedQueueingProcessor.cancelWorks(BatchedQueueingProcessor.java:180)
>         at org.hibernate.search.backend.impl.PostTransactionWorkQueueSynchronization.afterCompletion(PostTransactionWorkQueueSynchronization.java:56)
>         at com.sun.enterprise.distributedtx.J2EETransaction.commit(J2EETransaction.java:491)
> The method body for this is:
> 	public void clear() {
> 		queue.clear(); // <---- queue is null
> 		if (sealedQueue != null) sealedQueue.clear();
> 	}
> It appears that queue may be set null by the setSealedQueue method above:
> 	public void setSealedQueue(List<LuceneWork> sealedQueue) {
> 		//invalidate the working queue for serializability
> 		queue = null;
> 		this.sealedQueue = sealedQueue;
> 	}
> The only change I've made recently that I thought could cause this was to change the search system to run in a separate thread.  My hibernate search options are:
>         <exclude-unlisted-classes>true</exclude-unlisted-classes>
> 		<properties>
>     		<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
>             <property name="hibernate.show_sql" value="false"/>
>             <property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.EhCacheProvider"/>
>             <property name="hibernate.cache.use_query_cache" value="true"/>
>             <property name="hibernate.cache.use_second_level_cache" value="true"/>
>             <property name="hibernate.bytecode.provider" value="javassist"/>
>             <property name="hibernate.search.default.directory_provider" value="org.hibernate.search.store.FSDirectoryProvider"/>
>             <property name="hibernate.search.default.indexBase" value="../search-indexes"/>
>             <property name="hibernate.search.worker.scope" value="books.db.search.SafeWorkerImpl"/>
>             <property name="hibernate.search.worker.backend" value="books.db.search.SafeBackendQueueProcessorFactory"/>
>             <property name="hibernate.search.worker.execution" value="async"/> <!-- sync or async -->
>             <property name="hibernate.search.worker.buffer_queue.max" value="5"/>
>             <property name="hibernate.search.worker.thread_pool.size" value="5"/>
> 		</properties>
> Note that books.db.search.Safe* are classes I wrote that wrap the default implementation with an exception handler; sometimes RuntimeExceptions were thrown and glassfish would just silently eat them and fail, now they are noisily eaten and the transaction commits anyway.
> This was probably (to some degree) triggered by the exception logged just prior:
> [#|2009-09-17T06:23:56.498-0700|SEVERE|sun-appserver9.1|org.hibernate.event.def.AbstractFlushingEventListener|_ThreadID=40;_ThreadName=httpSSLWorkerThread-8080-19;_RequestID=97e3df6c-2fc7-4f54-a47a-e77ba48d1a07;|Could not synchronize database state with session
> org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [books.db.Business#5617057]
>         at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:1782)
>         at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2425)
>         at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2325)
>         at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2625)
>         at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:115)
>         at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
>         at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
>         at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:168)
>         at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
>         at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
>         at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1028)
>         at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:366)
>         at org.hibernate.ejb.AbstractEntityManagerImpl$1.beforeCompletion(AbstractEntityManagerImpl.java:504)
>         at com.sun.enterprise.distributedtx.J2EETransaction.commit(J2EETransaction.java:419)
> Figuring out under which conditions the queue became null but shouldn't have been might be nearly impossible at this point, although I'll watch out for repeats of this issue.
> The NPE itself might be easier to fix, if you just check for null before calling clear().
> For now I'll try implementing a workaround in my safe subclass like this:
>     @Override
>     public void cancelWorks(WorkQueue workQueue) {
>         try {
>             super.cancelWorks(workQueue);
>         } catch (RuntimeException e) {
>             logger.error("RuntimeException during cancelWorks()", e);
>         	try {
> 	        	if(workQueue.getQueue() != null)
> 	        		workQueue.getQueue().clear();
> 	        	else
> 	        		workQueue.getSealedQueue().clear();
>         	} catch(org.hibernate.annotations.common.AssertionFailure t) {
>         		// sealedQueue was null too
>         	}
>         }
>     }

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        


More information about the hibernate-issues mailing list