Hibernate version:3.2
Database: Oracle 10gR2
Hi I am facing an issue in cascading delete when I try to delete a parent entity. The mapping files are as given below:
Code:
<hibernate-mapping>
<class name="com.blah.User" table="USER">
<id name="userId" type="long">
<column name="USER_ID" precision="10" scale="0" />
<generator class="sequence">
<param name="sequence">USER_ID_SEQ</param>
</generator>
</id>
<property name="userName" type="string">
<column name="USER_NAME" length="50" />
</property>
<bag name="userRoles" inverse="true" cascade="all, delete-orphan" lazy="false">
<key>
<column name="USER_ID" precision="10" scale="0" not-null="true" />
</key>
<one-to-many class="com.blah.UserRole" />
</bag>
</class>
<class name="com.blah.Role" table="ROLE">
<id name="roleId" type="long">
<column name="ROLE_ID" precision="10" scale="0" />
<generator class="sequence">
<param name="sequence">ROLE_ID_SEQ</param>
</generator>
</id>
<property name="roleName" type="string">
<column name="ROLE_NAME" length="50" />
</property>
<bag name="userRoles" inverse="true" cascade="all, delete-orphan" lazy="false">
<key>
<column name="ROLE_ID" precision="10" scale="0" not-null="true" />
</key>
<one-to-many class="com.blah.UserRole" />
</bag>
</class>
<class name="com.blah.UserRole" table="USER_ROLES">
<composite-id name="id" class="com.blah.UserRoleId">
<key-many-to-one name="user"
column="USER_ID" class="com.blah.User" lazy="false" />
<key-many-to-one name="role"
column="ROLE_ID" class="com.blah.Role" lazy="false" />
</composite-id>
</class>
</hibernate-mapping>
The cascading saves are happening properly. But when I try to delete the User object, then it gives the following exception:
Code:
org.springframework.dao.InvalidDataAccessApiUsageException: deleted object would be re-saved by cascade (remove deleted object from associations): [com.blah.UserRole#com.blah.UserRoleId@a92aaa]; nested exception is org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): [com.blah.UserRole#com.blah.UserRoleId@a92aaa]
Caused by: org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): [com.blah.UserRole#com.blah.UserRoleId@a92aaa]
at org.hibernate.impl.SessionImpl.forceFlush(SessionImpl.java:1014)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:168)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:98)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:507)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:499)
at org.hibernate.engine.CascadingAction$5.cascade(CascadingAction.java:218)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:268)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:216)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:296)
at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:242)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:219)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
at org.hibernate.engine.Cascade.cascade(Cascade.java:130)
at org.hibernate.event.def.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:131)
at org.hibernate.event.def.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:122)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:65)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:561)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:611)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:581)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:307)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:117)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:176)
at org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor.invoke(ThrowsAdviceInterceptor.java:125)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:176)
at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:51)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:176)
at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:53)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:176)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:210)
I was tried giving simple property in the UserRole mapping with many-to-one to the User and Role associations with insert and update=false, but in this case the cascading save doesnot happen when I try to save a new User along with its roles. But giving key-many-to-one is causing the above exception. It seems that the Role object is holding the reference to the UserRoles eventhough I am trying to delete the objects from the User end of the association. My success criteria is to delete both the User and the UserRole entry leaving the Role entry in the DB as such. I have done a temporary solution of iterating the UserRoles assiociation and removing the UserRole from the Role object collection manually and then calling a clear on the User.userRoles before calling delete. But this is not an elegant way to this problem. I can not modify the DB to provide any synthetic keys to the association table. Any help is appreciated.
Thanks,
Rajesh