I am facing issue regarding hibernate rollback handling in MyIsam.
I am using hibernate + Spring + MySQL 5.0.
I have 2 entities with following relationship in my code:
Stationery 1... * BookContent
Stationery.hbm.xml has following:
Code:
<set
name="bookContentList"
lazy="true"
inverse="true"
cascade="save-update"
sort="unsorted"
batch-size="10"
>
<key
column="Stationery_ID"
>
</key>
<one-to-many
class="com.myclass.BookContentEntity"
/>
</set>
When I try to insert StationeryEntity with bookContent set in it, the operation throws an exception while inserting into BookContent table(because of DB contraint whick is OK ). But the row that has been inserted into parent StationeryEntity table is not deleted.
I understand that this is because MyIsam is not a tx DB and does not rollback the tx. So I try to catch the DB exception and delete the StationeryEntity myself. But hibernate does not allow me to do so.
Code:
void saveContent(){
try{
BookContent bc= new BookContent();
bc.setCode("12345");// the code would cause a duplicate key exception in Bookcontent table
Long contentId = StationeryEntityManager.insertEntity(StationeryEntity);
}catch (Exception e)
{
StationeryEntityManager.deleteEntity(StationeryEntity);
}
)
It gives following exception :
16:23:21,358 ERROR [AssertionFailure] 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 com.myclass.BookContentEntity entry (don't flush the Session after an exception occurs)
at org.hibernate.event.def.DefaultFlushEntityEventListener.checkId(DefaultFlushEntityEventListener.java:48)
at org.hibernate.event.def.DefaultFlushEntityEventListener.getValues(DefaultFlushEntityEventListener.java:150)
at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:106)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:195)
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:980)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:353)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
a.
.
.
.
.
.
6:23:21,373 DEBUG [HibernateTransactionManager] Rolling back Hibernate transaction on Session [org.hibernate.impl.SessionImpl@c27081]
16:23:21,373 DEBUG [JDBCTransaction] rollback
16:23:21,373 DEBUG [JDBCTransaction] re-enabling autocommit
16:23:21,373 DEBUG [JDBCTransaction] rolled back JDBC Connection
16:23:21,373 DEBUG [JDBCContext] after transaction completion
16:23:21,373 DEBUG [ConnectionManager] transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources!
16:23:21,373 DEBUG [SessionImpl] after transaction completion
in transactionconfig.xml :
<bean id="transactionAttributes" class="org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource">
<property name="properties">
<value>
insertContent*=PROPAGATION_REQUIRED,-Exception
deleteEntity*=PROPAGATION_REQUIRED,+Exception
</value>
</property>
</bean
I believe that hibernate tries delete StationeryEntity and associated BookContent Entity but it finds bookcontentid =null (bookcontent was not inserted in DB due to duplicate constraint) and rollback the delete operation .As a result even the content table row is not deleted
I even tried to force delete commit by deleteEntity*=PROPAGATION_REQUIRED,+Exception
but it doesnt work. Can any one tell me what strategy should be adopted for rollback in this case.