-->
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.  [ 5 posts ] 
Author Message
 Post subject: all-delete-orphan and moving children between parents
PostPosted: Sat Aug 27, 2011 8:12 pm 
Newbie

Joined: Wed Jun 08, 2011 3:29 am
Posts: 7
Hello,
I have the following problem. I need to use all-delete-orphan for the collection in the parent class, just like this:
Code:
    <list name="branches" cascade="all-delete-orphan" inverse="false">
      <key column="SECTION_ID" />
      <index column="BRANCHES_INDEX" />
      <one-to-many class="Branch" />
    </list>

And I want to delete one parent moving all its children to another parent (recipient), just like this:
Code:
    public boolean deleteAndMoveBranchesTo(Long victimId, Long recipientId) {
        Section victim = (Section) getSession().load(Section.class, victimId);
        Section recipient = (Section) getSession().load(Section.class, recipientId);
        for (Branch branch : victim.getBranches()) {
            branch.setSection(recipient);
            getSession().saveOrUpdate(branch);
        }
        recipient.getBranches().addAll(victim.getBranches());
        victim.getBranches().clear();
        saveOrUpdate(recipient);
        getSession().delete(victim);
        return true;
    }

But this code cause following error:
Code:
org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): [org.jtalks.poulpe.model.entity.Branch#1]
   at org.hibernate.impl.SessionImpl.forceFlush(SessionImpl.java:1042)
   at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:188)
   at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:117)
   at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
   at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:535)
   at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:527)
   at org.hibernate.engine.CascadingAction$5.cascade(CascadingAction.java:241)
   at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:292)
   at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:240)
   at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:193)
   at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:320)
   at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:266)
   at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:243)
   at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:193)
   at org.hibernate.engine.Cascade.cascade(Cascade.java:154)
   at org.hibernate.event.def.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:154)
...


So how can I combine all-delete-orphan, deletion of parent Section and moving all its children (Branches) to another Section?

It looks like this topic is related with https://forum.hibernate.org/viewtopic.php?p=2350533

Best regards, Dmitriy.


Top
 Profile  
 
 Post subject: Re: all-delete-orphan and moving children between parents
PostPosted: Sat Aug 27, 2011 11:12 pm 
Beginner
Beginner

Joined: Sat May 21, 2011 7:40 am
Posts: 22
You could try to flush the session right after moving the branches and after that removing victim.


Top
 Profile  
 
 Post subject: Re: all-delete-orphan and moving children between parents
PostPosted: Sun Aug 28, 2011 3:19 am 
Newbie

Joined: Wed Jun 08, 2011 3:29 am
Posts: 7
christianbeikov wrote:
You could try to flush the session right after moving the branches and after that removing victim.
It didn't help, I changed the method in the following way:
Code:
...
        getSession().saveOrUpdate(recipient);
        getSession().flush();
        victim.getBranches().clear();
        getSession().delete(victim);
but I still get "deleted object would be re-saved by cascade (remove deleted object from associations)" exception.

Maybe it's worth to say that whole this method is in a transaction.


Top
 Profile  
 
 Post subject: Re: all-delete-orphan and moving children between parents
PostPosted: Sun Aug 28, 2011 9:43 am 
Beginner
Beginner

Joined: Sat May 21, 2011 7:40 am
Posts: 22
The transaction should not be the problem, you can still try to clear the session after adding the elements.
I think the "problem" here is the Unit-of-Work Pattern which is implemented by Hibernate.
I don't remember the right order of actions but i think it was

1. Delete
2. Save
3. Update

The problem is that you delete your entities after saving them to other entities. But Hibernate wants to execute delete before saving but still holds the object in the Session map. Because of that i think that you get this exception. You will need to flush the session that the save is written to the db and clear the session then.
After that you should be able to delete the victim(Also try to reload the victim from the db if other things don't work).
If nothing helps, your last chance is probably writing a delete-query.

Just for me to know:
Branch has a many to one association to section, so why do you clear the branches collection of the victim?
You just need to update the branches and delete the victim!


Top
 Profile  
 
 Post subject: Re: all-delete-orphan and moving children between parents
PostPosted: Sun Aug 28, 2011 11:23 am 
Newbie

Joined: Wed Jun 08, 2011 3:29 am
Posts: 7
christianbeikov wrote:
You will need to flush the session that the save is written to the db and clear the session then.
After that you should be able to delete the victim(Also try to reload the victim from the db if other things don't work).
Thanks! You saved me, everything works now. I did it in the following way:
Code:
public boolean deleteAndMoveBranchesTo(Long victimId, Long recipientId) {
        Section victim = (Section) getSession().load(Section.class, victimId);
        Section recipient = (Section) getSession().load(Section.class, recipientId);
        for (Branch branch : victim.getBranches()) {
            branch.setSection(recipient);
        }
        recipient.getBranches().addAll(victim.getBranches());
        // victim.getBranches().clear(); // DOESN'T WORK WITH THIS!
        getSession().saveOrUpdate(recipient);
        getSession().flush();
        getSession().evict(victim);
        victim = (Section) getSession().load(Section.class, victimId);
        getSession().delete(victim);
        return true;
    }


Quote:
Branch has a many to one association to section, so why do you clear the branches collection of the victim?
You just need to update the branches and delete the victim!
Yeah, I know, but nothing else works so I added it just in case. (not sure maybe it was necessary to use cascade=all, don't remember for sure).

Ones more, thank you very much! ;)


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

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.