-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 11 posts ] 
Author Message
 Post subject: Access a Sealed WorkQueue which has not been sealed
PostPosted: Wed Jun 03, 2009 12:16 pm 
Newbie

Joined: Wed Jun 03, 2009 11:54 am
Posts: 9
Hi,

I'm not sure, if this is a hibernate search problem or a resin server related problem (or my code :o). But currently I'm getting exception "Access a Sealed WorkQueue which has not been sealed", when commiting the transaction. This exception occurs in "PostTransactionWorkQueueSynchronization.afterCompletion", which subsequently calls "queueingProcessor.performWorks", but as the "queueingProcessor.prepareWorks" has never been called, it throws an exception.
It seems, that hibernate search registers a new synchronization during "callBeforeCompletion" and it expects, that this synchronization will be called after this "callBeforeCompletion" is finished. At least my version of Resin does not allow this. It does call the "callAfterCompletion", but not the "callBeforeCompletion". The reason is, that Resin uses an ArrayList to store the synchronizations and as it is already traversing the list, it does not call the newly added synchronization. Here is the code from Resin:

private void callBeforeCompletion()
throws RollbackException
{
int length = _syncList == null ? 0 : _syncList.size();

for (int i = 0; i < length; i++) {
Synchronization sync = _syncList.get(i);

try {
sync.beforeCompletion();
} catch (RuntimeException e) {
throw new RollbackException(e);
} catch (Throwable e) {
log.log(Level.FINE, e.toString(), e);
}
}

And this is the stack trace:

TransactionImpl.registerSynchronization(Synchronization) line: 513
JTATransaction.registerSynchronization(Synchronization) line: 313
EventSourceTransactionContext.registerSynchronization(Synchronization) line: 56
TransactionalWorker.performWork(Work, TransactionContext) line: 47
FullTextIndexEventListener.processWork(T, Serializable, WorkType, AbstractEvent) line: 128
FullTextIndexEventListener.onPostUpdate(PostUpdateEvent) line: 120
EntityUpdateAction.postUpdate() line: 200
EntityUpdateAction.execute() line: 179
ActionQueue.execute(Executable) line: 279
ActionQueue.executeActions(List) line: 263
ActionQueue.executeActions() line: 168
DefaultFlushEventListener(AbstractFlushingEventListener).performExecutions(EventSource) line: 321
DefaultFlushEventListener.onFlush(FlushEvent) line: 50
SessionImpl.flush() line: 1027
SessionImpl.managedFlush() line: 365
CacheSynchronization.beforeCompletion() line: 88
TransactionImpl.callBeforeCompletion() line: 832
TransactionImpl.commit() line: 564
TransactionManagerImpl.commit() line: 261
UserTransactionImpl.commit() line: 407
UserTransactionProxy.commit() line: 138
JTASupport.commit() line: 73

Is it problem of hibernate search or Resin server? I'm not sure what the specs say... or is it just my code?


Top
 Profile  
 
 Post subject: Re: Access a Sealed WorkQueue which has not been sealed
PostPosted: Thu Jun 04, 2009 9:06 am 
Newbie

Joined: Wed Jun 03, 2009 11:54 am
Posts: 9
I tried to fix it in Resin code, but it did not help. Even if the "queueingProcessor.prepareWorks" is called, it throws a "NullPointerException" with the following stack trace:

java.lang.NullPointerException
at org.hibernate.search.backend.WorkQueue.add(WorkQueue.java:31)
at org.hibernate.search.backend.impl.BatchedQueueingProcessor.add(BatchedQueueingProcessor.java:108)
at org.hibernate.search.backend.impl.PostTransactionWorkQueueSynchronization.add(PostTransactionWorkQueueSynchronization.java:39)
at org.hibernate.search.backend.impl.TransactionalWorker.performWork(TransactionalWorker.java:50)
at org.hibernate.search.event.FullTextIndexEventListener.processWork(FullTextIndexEventListener.java:128)
at org.hibernate.search.event.FullTextIndexEventListener.onPostUpdate(FullTextIndexEventListener.java:120)
at org.hibernate.action.EntityUpdateAction.postUpdate(EntityUpdateAction.java:200)
at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:179)
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.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:64)
at org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:996)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1141)
at org.hibernate.impl.QueryImpl.list(QueryImpl.java:102)

Any idea what am I doing wrong?

Thank you,
p.


Top
 Profile  
 
 Post subject: Re: Access a Sealed WorkQueue which has not been sealed
PostPosted: Thu Jun 04, 2009 9:58 am 
Newbie

Joined: Wed Jun 03, 2009 11:54 am
Posts: 9
I'm not sure if this helps and if somebody is going to reply to my post :o), but it seems, that hibernate search is trying to add a new "UPDATE" work to a work queue that had been sealed and contains "DeleteLuceneWork" and "AddLuceneWork"... and that fails with NullPointerException... and this happens during a simple query with a where condition like: "FROM Clazz WHERE attribute1.attribute = :param1 AND attribute2 = :param2"

These are the WorkQueue values, when it fails executing "queue.add(work);"

this WorkQueue (id=244)
queue null
sealedQueue ArrayList<E> (id=255)
elementData Object[3] (id=281)
[0] DeleteLuceneWork (id=283)
batch false
document null
entityClass Class<T> (PolyRingTone) (id=266)
id Integer (id=291)
idInString "3561"
[1] AddLuceneWork (id=284)
batch false
document Document (id=297)
entityClass Class<T> (PolyRingTone) (id=266)
fieldToAnalyzerMap null
id Integer (id=291)
idInString "3561"

work Work<T> (id=263)
entity PolyRingTone (id=265)
entityClass null
id Integer (id=269)
idGetter null
type WorkType (id=272)
name "UPDATE"
ordinal 1
searchForContainers true


Top
 Profile  
 
 Post subject: Re: Access a Sealed WorkQueue which has not been sealed
PostPosted: Thu Jun 04, 2009 10:52 am 
Newbie

Joined: Wed Jun 03, 2009 11:54 am
Posts: 9
OK, the problem is most probably caused by the auto flush. In case the auto flush is performed in a transaction, hibernate search seals the work queue... So I'm gonna try to reorganize the code and hopefully it helps...


Top
 Profile  
 
 Post subject: Re: Access a Sealed WorkQueue which has not been sealed
PostPosted: Thu Jun 04, 2009 11:09 am 
Hibernate Team
Hibernate Team

Joined: Thu Apr 05, 2007 5:52 am
Posts: 1689
Location: Sweden
It would help if you could post some of the code you are executing. For example your annotated entities and the code between a Session creation and closing. Are you sure your transaction management is properly setup? At which point does this exception occur.

Have you verified that this behavior is Resin specfic? Have you tried to deploy your code into another container? This could help narrow down your problem.
Maybe you could even create some simple testcase we could run to verify your problem.

--Hardy


Top
 Profile  
 
 Post subject: Re: Access a Sealed WorkQueue which has not been sealed
PostPosted: Thu Jun 04, 2009 11:28 am 
Newbie

Joined: Wed Jun 03, 2009 11:54 am
Posts: 9
I'll try to create a test case later. Afterwards I can also try it with different app server (even that after my fix the Transaction implementation looks practically the same as in glassfish - from what I've seen).
But first I want to find out, why was it marked for "auto flush", because I did not want to have it this way :)...


Top
 Profile  
 
 Post subject: Re: Access a Sealed WorkQueue which has not been sealed
PostPosted: Thu Jun 04, 2009 4:47 pm 
Newbie

Joined: Wed Jun 03, 2009 11:54 am
Posts: 9
The problem is probably, that the "TransactionalWorker.performWork" method expects, that the "transactionIdentifier" will change after the transaction is commited. But this does not happen in my case. The reason is that "JDBCContext.afterTransactionCompletion()" is not called after the transaction is commited, so the member variable "hibernateTransaction" does not change the value. So if I begin a new Transaction using the same Session and the previous transaction has been commited (so the WorkQueue has been sealed), I get the mentioned "NullPointerException". I'm not sure what means the comment in the JDBCContext class: "We cannot rely upon this method being called! It is only called if we are using Hibernate Transaction API.", but I have the feeling, that exactly this is happening in my case...

public void performWork(Work work, TransactionContext transactionContext) {
if ( transactionContext.isTransactionInProgress() ) {
Object transactionIdentifier = transactionContext.getTransactionIdentifier();
PostTransactionWorkQueueSynchronization txSync = ( PostTransactionWorkQueueSynchronization )
synchronizationPerTransaction.get( transactionIdentifier );

if ( txSync == null || txSync.isConsumed() ) {
txSync = new PostTransactionWorkQueueSynchronization(
queueingProcessor, synchronizationPerTransaction
);
transactionContext.registerSynchronization( txSync );
synchronizationPerTransaction.put( transactionIdentifier, txSync );
}
txSync.add( work );
}


/**
* We cannot rely upon this method being called! It is only
* called if we are using Hibernate Transaction API.
*/

public void afterTransactionBegin(Transaction tx) {
log.trace( "after transaction begin" );
owner.afterTransactionBegin(tx);
}

public void afterTransactionCompletion(boolean success, Transaction tx) {
log.trace( "after transaction completion" );

if ( getFactory().getStatistics().isStatisticsEnabled() ) {
getFactory().getStatisticsImplementor().endTransaction(success);
}

connectionManager.afterTransaction();

isTransactionCallbackRegistered = false;
hibernateTransaction = null;
owner.afterTransactionCompletion(success, tx);
}


Top
 Profile  
 
 Post subject: Re: Access a Sealed WorkQueue which has not been sealed
PostPosted: Thu Jun 04, 2009 5:23 pm 
Newbie

Joined: Wed Jun 03, 2009 11:54 am
Posts: 9
If I call "JDBCContext.afterTransactionCompletion" manually or I just close the Session always after the transaction is commited, then everything works just fine. So currently the workaround for JTA transactions is either to close the session (I preffer this one) or do something like this:

JDBCContext jdbcContext = fullTextSession.getSession(EntityMode.POJO).getJDBCContext();
jdbcContext.afterTransactionCompletion(true, jdbcContext.getTransaction());

And this problem seems to be more "hibernate core" related, than "hibernate search"...


Top
 Profile  
 
 Post subject: Re: Access a Sealed WorkQueue which has not been sealed
PostPosted: Thu Jun 04, 2009 5:32 pm 
Newbie

Joined: Wed Jun 03, 2009 11:54 am
Posts: 9
And I'm still not sure, if registering a new Synchronization (my first post) in a commit is right thing to do... at least I have not found anything about it in the JTA spec, so the behaviour of the app server might be unpredictable... as I mentioned before, f.e. Resin server does not call then the "beforeCompletion" method, only the "afterCompletion" method...


Top
 Profile  
 
 Post subject: Re: Access a Sealed WorkQueue which has not been sealed
PostPosted: Tue May 03, 2011 5:03 am 
Beginner
Beginner

Joined: Mon Apr 04, 2011 12:08 pm
Posts: 32
this problem doesn't seem to be fixed in recent hibernate serach versions viewtopic.php?f=9&t=1010772


Top
 Profile  
 
 Post subject: Re: Access a Sealed WorkQueue which has not been sealed
PostPosted: Tue Oct 11, 2011 4:28 am 
Newbie

Joined: Wed Sep 21, 2011 9:34 am
Posts: 6
This error means that you're trying to access a lazily-loaded property or collection, but the hibernate session is closed. Lazy loading in Hibernate means that the object will not be populated (via a database query) until the property/collection is accessed in code. Hibernate accomplishes this by creating a dynamic proxy object that will hit the database only when you first use the object. In order for this to work, your object must be attached to an open Hibernate session throughout it's lifecycle. Check to see how you're managing your session. You may need to reattach objects to a new session if the session is being closed in some other place.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 11 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.