farzad wrote:
Why don't you try again on a ConstraintViolationException? A second failure though doesn't look good. In addition, you might want to set your transaction isolation level to READ COMMITED if the first transaction has a chance of failure after inserting the data.
Farzad-
When the second transaction T2 is committed, a DataIntegrityViolationException is thrown. In the catch block of this exception, we try to read -
officeManager.getByOfficeNr(officeNr) - the value of the client number in the database. Before doing the read, Hibernate automatically flushes the session.
Code:
if (effectiveOffice == null)
{
// Attempt to create the office entity but recover on duplicate key (concurrent thread).
try
{
// Create the office entity into the database.
officeManager.create(candidateOffice);
}
catch (DataIntegrityViolationException exception)
{
// Retrieve the office entity created by the concurrent thread.
effectiveOffice = officeManager.getByOfficeNr(officeNr);
}
}
When doing the retry Hibernate generates "don't flush the Session after an exception occurs". The stacktrace received when executing
effectiveOffice = officeManager.getByOfficeNr(officeNr); is included underneath.
Code:
cause = org.hibernate.AssertionFailure: null id in com.notary.app.invoicing.core.fwk.model.OfficeImpl entry (don't org.hibernate.event.def.DefaultFlushEntityEventListener.getValues(DefaultFlushEntityEventListener.java:157)
org.hibernate.AssertionFailure - null id in com.notary.app.invoicing.core.fwk.model.OfficeImpl entry (don't flush the Session after an exception occurs)
by org.hibernate.event.def.DefaultFlushEntityEventListener.checkId(DefaultFlushEntityEventListener.java:55)
StackTrace on org.hibernate.AssertionFailure
org.hibernate.event.def.DefaultFlushEntityEventListener.checkId(DefaultFlushEntityEventListener.java:55)
org.hibernate.event.def.DefaultFlushEntityEventListener.getValues(DefaultFlushEntityEventListener.java:157)
org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:113)
org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:196)
org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:76)
org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:35)
org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:969)
org.hibernate.impl.SessionImpl.list(SessionImpl.java:1114)
org.hibernate.impl.QueryImpl.list(QueryImpl.java:79)
org.springframework.orm.hibernate3.HibernateTemplate$29.doInHibernate(HibernateTemplate.java:849)
org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:372)
org.springframework.orm.hibernate3.HibernateTemplate.find(HibernateTemplate.java:840)
com.notary.app.invoicing.core.fwk.dao.OfficeDAOImpl.getByOfficeNr(OfficeDAOImpl.java:75)
Is there a way to influence the behavior of
autoFlushIfRequired ?
Regards, Stefan Lecho.