Ok, so I've been banging my head against the wall for a couple days now, but I've finally narrowed down this bug enough that I think I know what's happening, but what I'm not sure of is how to fix it. Given that I'm using spring to interact with hibernate, I'm not even 100% sure whether I should post this here or on the spring forums, but I'm going to start here since this appears to be related to a potential transaction bug. I'm running Hibernate-core v3.3.0.SP1; hibernate-annotations v3.4.0.GA, and hibernate-commons-annotations v3.1.0.GA
Basically what's happening is as follows:
I've got three methods involved in this,
Code:
private void driveDataLoad()
(outside of all transactions)
Code:
@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
public DataMergeReport loadData(int famId, int fileId, int numRowsToLoad)
and
Code:
@Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = false)
private synchronized void loadRow(int famId, Row row, List<String> fieldNames, int fileId, int rowNumber)
I'm trying to catch and handle a DataIntegrityViolationException in
Code:
loadRow()
by capturing it, creating a new exception of my own that adds some information about what was happening when it was thrown, then throwing that up to
Code:
loadData()
, which in turn captures the exception, adds a little more information and throws that back up to
Code:
driveDataLoad()
, which in turn takes the information, persists the exception log to the database so it can be nicely displayed for the user, and then ends the data loading thread.
What appears to be happening, however, is that somewhere between where the exception is re-thrown in
Code:
loadData()
and it being caught in
Code:
driveDataLoad()
, hibernate attempts to commit the transaction, which of course throws an exception. Here's the log:
Quote:
************ C <--Immediately prior to when the exception is thrown up from
Code:
loadData()
to
Code:
driveDataLoad()
17 May 2011 10:22:15,359 - commit
17 May 2011 10:22:15,363 - an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session)
org.hibernate.AssertionFailure: null id in DpuCARData entry (don't flush the Session after an exception occurs)
at org.hibernate.event.def.DefaultFlushEntityEventListener.checkId(DefaultFlushEntityEventListener.java:55)
at org.hibernate.event.def.DefaultFlushEntityEventListener.getValues(DefaultFlushEntityEventListener.java:164)
at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:120)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:196)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:76)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1001)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:339)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:655)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:732)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:701)
at org.springframework.transaction.interceptor.TransactionAspectSupport.completeTransactionAfterThrowing(TransactionAspectSupport.java:359)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:635)
at net.intellidata.dpu.DataMerger$$EnhancerByCGLIB$$de1c6bf.loadData(<generated>)
at net.intellidata.dpu.thread.DataMergeProgressThread.driveDataLoad(DataMergeProgressThread.java:144)
at net.intellidata.dpu.thread.DataMergeProgressThread.run(DataMergeProgressThread.java:104)
17 May 2011 10:22:15,367 - rollback
17 May 2011 10:22:15,384 - re-enabling autocommit
17 May 2011 10:22:15,385 - rolled back JDBC Connection
17 May 2011 10:22:15,385 - Application exception overridden by commit exception
net.intellidata.dpu.DataMergeException: Data Integrity Violation
...
Any suggestions for how I might remedy this would be welcome.
Thanks!