Hello all,
I have recently stumbled upon a a fairly nasty issue with Hibernate used in a concurrent environment. I have one entity class that references a collection of composite objects. This is the relationship defined in Xdoclet markup:
* @hibernate.set table="CUSTOM_VALUES" lazy="false" cascade="all"
* @hibernate.collection-key column="VALUE_ID"
* @hibernate.collection-composite-element class="com.test.Value"
* @hibernate.collection-many-to-one column="FK_VALUE_ID"
* class="com.test.MainEntity"
* not-null="true"
I am able to add/remove elements to the collection referenced by "MainEntity" just fine. However, it appears that when I use a Hibernate query to get all of the "MainEntity" instances, I get errors from Hibernate when the query is executed concurrently. In other words, if I have two different threads trying to perform the same query to get all of the MainEntity instances, I get exceptions like the following:
Caused by: org.hibernate.exception.GenericJDBCException: could not delete collection rows: [com.test.MainEntity.customValues#638]
at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:91)
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:79)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.persister.collection.AbstractCollectionPersister.deleteRows(AbstractCollectionPersister.java:1140)
at org.hibernate.action.CollectionUpdateAction.execute(CollectionUpdateAction.java:54)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:243)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:227)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:143)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:296)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:980)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:353)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at
Caused by: org.firebirdsql.jdbc.FBSQLException: GDS Exception. 335544382. cannot update erased record
It appears that Hibernate is first deleting the underlying records from the database while it is performing the query... Why is this? If all of the data is already available in the database, why would it be deleting anything while populating the MainEntity objects? Is there some way that I can get around this behavior with introducing some sort of external synchronization to the query logic?
Any help is greatly appreciated....
Thanks!
Ryan
|