-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 
Author Message
 Post subject: Problem with inverse="true", maybe a BUG in hibern
PostPosted: Fri Mar 04, 2005 7:18 am 
Newbie

Joined: Fri Mar 04, 2005 6:54 am
Posts: 1
Hello,
I have a problem using two One-to-Many relations.
I have three pojos:
------ ------------- --------
|User| <-- |UserGroup| --> |Group|
------- -------------- --------
| |
Set One-to-Many_UserGroup |
set One-to-Many_UserGroup

each pojo User and Group have a One-to-Many relationships to UserGroup, I know this is equivalente to having a Many-to-Many relationship between User and Group, but i need it as two One-to-Many associations.
I have cascading set to all in the associations as demonstrated in the hbm's that will follow.

The problem is that:
- when i remove a user through cascading the entrys in UserGroup table will be removed. Hibernate will force a flush in the session and try to update the associations from the Pojo Group. I have set inverse="true" in the association to prevent Hibernate from trying to re-save the object that was deleted.
When hibernate is trying to update the Group Pojo association the folowing exception is thrown:


org.springframework.orm.hibernate.HibernateObjectRetrievalFailureException: deleted object would be re-saved by cascade (remove deleted object from associations): 5, of class: pt.gedi.siag.persistence.ASUtilizadorGrupo;
nested exception is net.sf.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): 5, of class: pt.gedi.siag.persistence.ASUtilizadorGrupo
net.sf.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): 5, of class: pt.gedi.siag.persistence.ASUtilizadorGrupo
at net.sf.hibernate.impl.SessionImpl.forceFlush(SessionImpl.java:753)
at net.sf.hibernate.impl.SessionImpl.save(SessionImpl.java:731)
at net.sf.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:1377)
at net.sf.hibernate.engine.Cascades$4.cascade(Cascades.java:114)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:436)
at net.sf.hibernate.engine.Cascades.cascadeCollection(Cascades.java:526)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:452)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:503)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:482)
at net.sf.hibernate.impl.SessionImpl.preFlushEntities(SessionImpl.java:2674)
at net.sf.hibernate.impl.SessionImpl.flushEverything(SessionImpl.java:2251)
at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2240)
at net.sf.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:61)
at org.springframework.orm.hibernate.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:472)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:377)
at org.springframework.transaction.interceptor.TransactionAspectSupport.doCommitTransactionAfterReturning(TransactionAspectSupport.java:243)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:66)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:632)
at pt.gedi.siag.services.us.adminsistema.UsersServiceImpl$$EnhancerByCGLIB$$2bad1f3f.removeEntry(<generated>)
at pt.gedi.siag.services.us.adminsistema.test.UsersServiceTestCase.testRemoveUser(UsersServiceTestCase.java:69)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:421)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:305)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:186)


Because of my suspition that it could be a BUG, i tried to do another thing,
having the Group Pojo association One-To-Many_UserGroup attribute inverse="true", i tried:
groupPojo.getOneToManyUserGroupCollection().add( newUserGroupPojo );
and for my surprise this inserted in the UserGroup table the new data from the newUserGroupPojo.

For what i have read if the inverse attribute was false this behaviour was expected, for inverse="true" the data from the collection should'nt persisted to the Table.


Is this a bug, or do i have something wrong?
In my tests i have tried to put lazy="true" in the association and then ran the tests that passed but only because i didnt use the One-to-Many association from Group Pojo. When I used it the test throwed the same exception.
This proves that he tries to re-save the object from the One-to-Many collection in Group Pojo if it is loaded.
But with inverse="true" this shouldnt happen.

Anexed to the document follows my original hbm and pojos.


In the article "Inside explanation of inverse=true" in http://www.hibernate.org/155.html,

For Update = "false"
Code:
Parent p = (Parent) session.load(Parent.class, parentId);
Parent p2 = (Parent) session.load(Parent.class, parentId2);

c = (Child) session.find(
"from Child as child where child.parent = ?",
p, Hibernate.entity(Parent.class)).get(0);

p.getChildren().remove(c);
p2.getChildren().add(p);
Will do the following SQL queries
Hibernate: select parent0_.id as id from parent parent0_ where parent0_.id=? //get parent 1
Hibernate: select parent0_.id as id from parent parent0_ where parent0_.id=? //get parent 2
Hibernate: select child0_.id as id, child0_.parent_id as parent_id from child child0_ where (child0_.parent_id=? ) //get children

Hibernate: select child0_.id as id__, child0_.id as id, child0_.parent_id as parent_id from child child0_ where child0_.parent_id=?
Hibernate: select child0_.id as id__, child0_.id as id, child0_.parent_id as parent_id from child child0_ where child0_.parent_id=?
//load childrens of Parent 1 and 2 (can't avoid this see FAQ)
Relationship update is not executed because update is only done on the parent side.

My Settings:
(For the saque of this example i called the pojos User, UserGroup and Group, but the real names are ASUtilizador, ASUtilizadorGrupo and ASGrupo)
User.hbm.xml:
.....
<set
name="relOM_ASUtilizador_ASUtilizadorGrupo"
inverse="true"
cascade="all-delete-orphan"
lazy="false">
<key column="ChvEASUtilizador"/>
<one-to-many class="pt.gedi.siag.persistence.ASUtilizadorGrupo"/>
</set>
...

Group.hbm.xml:
...
<set
name="relOM_ASGrupo_ASUtilizadorGrupo"
inverse="true"
cascade="all">
<key column="ChvEASGrupo"/>
<one-to-many class="pt.gedi.siag.persistence.ASUtilizadorGrupo"/>
</set>
....

UserGroup.hbm.xml
...
<many-to-one
name="relMO_ASUtilizadorGrupo_ASGrupo"
class="pt.gedi.siag.persistence.ASGrupo"
column="ChvEASGrupo"
/>

<many-to-one
name="relMO_ASUtilizadorGrupo_ASUtilizador"
class="pt.gedi.siag.persistence.ASUtilizador"
column="ChvEASUtilizador"
/>
...




Hibernate version:2

Full stack trace of any exception that occurs:
org.springframework.orm.hibernate.HibernateObjectRetrievalFailureException: deleted object would be re-saved by cascade (remove deleted object from associations): 5, of class: pt.gedi.siag.persistence.ASUtilizadorGrupo;
nested exception is net.sf.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): 5, of class: pt.gedi.siag.persistence.ASUtilizadorGrupo
net.sf.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): 5, of class: pt.gedi.siag.persistence.ASUtilizadorGrupo
at net.sf.hibernate.impl.SessionImpl.forceFlush(SessionImpl.java:753)
at net.sf.hibernate.impl.SessionImpl.save(SessionImpl.java:731)
at net.sf.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:1377)
at net.sf.hibernate.engine.Cascades$4.cascade(Cascades.java:114)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:436)
at net.sf.hibernate.engine.Cascades.cascadeCollection(Cascades.java:526)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:452)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:503)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:482)
at net.sf.hibernate.impl.SessionImpl.preFlushEntities(SessionImpl.java:2674)
at net.sf.hibernate.impl.SessionImpl.flushEverything(SessionImpl.java:2251)
at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2240)
at net.sf.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:61)
at org.springframework.orm.hibernate.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:472)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:377)
at org.springframework.transaction.interceptor.TransactionAspectSupport.doCommitTransactionAfterReturning(TransactionAspectSupport.java:243)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:66)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:632)
at pt.gedi.siag.services.us.adminsistema.UsersServiceImpl$$EnhancerByCGLIB$$2bad1f3f.removeEntry(<generated>)
at pt.gedi.siag.services.us.adminsistema.test.UsersServiceTestCase.testRemoveUser(UsersServiceTestCase.java:69)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:421)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:305)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:186)


Name and version of the database you are using:mySQL Dist 3.2


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.