-->
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.  [ 4 posts ] 
Author Message
 Post subject: THE way to delete child objects using JPA + Hibernate
PostPosted: Wed Feb 04, 2009 12:41 pm 
Newbie

Joined: Tue Feb 03, 2009 11:23 am
Posts: 4
Hi

I've been fighting with how to delete child objects in a OneToMany all day. At first I didnt realise that JPA does not (yet) support delete-orphan, so although the link between my parent and child(ren) was being severed, the child was still in the Database.

Then I ran into all sorts of concurrent modification issues because I was using my collection in a for(Child c: children).... loop, and of course, calling children.remove(c) in this case will cause that problem.

So, based on the other posts I've read, I think I have the solution, which is shown below in case it's helpful to other people who are beginners like me

Code:
        FileType fileType = findFileType(fileTypeId);
        Iterator it = fileType.getFields().iterator();
        while(it.hasNext()) {
            Field f = (Field)it.next();
            if(fieldIds.contains(f.getFieldId())) {
                it.remove();
                entityManager.remove(f);  // this bit required because JPA doesnt support delete-orphan
            }           
        }


Here's my mapping btw - it uses the default cascade behaviour (ALL) and uses a join table

Code:
@OneToMany(fetch=FetchType.LAZY)
    @JoinTable(
            name="FILE_TYPE_FIELD",
            joinColumns = @JoinColumn(name="FILE_TYPE_ID", referencedColumnName="FILE_TYPE_ID"),
            inverseJoinColumns = @JoinColumn(name="FILE_FIELD_ID", referencedColumnName="FILE_FIELD_ID")
    )


What I would really appreciate is if someone could just say yeah (or no), this is the standard way of doing things, because I struggled a bit finding good examples, and I am going to be writing a whole load of these soon so I want to do them right :)

Also, for bonus points, the docs recommend using a join table, even though a simple foreign key would suffice. Why is this?

Thanks


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 04, 2009 12:47 pm 
Expert
Expert

Joined: Thu Jan 08, 2009 6:16 am
Posts: 661
Location: Germany
Was it not possible for you to use
@org.hibernate.annotations.Cascade(CascadeType.DELETE_ORPHAN) or do you want to use JPA-Annotations only?

_________________
-----------------
Need advanced help? http://www.viada.eu


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 04, 2009 1:01 pm 
Newbie

Joined: Tue Feb 03, 2009 11:23 am
Posts: 4
Hmm, yeah that works. I did try it earlier but because I was tying myself in knots because of the loop issue, I took it out again.

So, changing the mapping to the following works (as long as I also add CascadeType=ALL)

@OneToMany(fetch=FetchType.LAZY, cascade=CascadeType.ALL)
@org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
@JoinTable(
name="BULK_UPLOAD_FILE_TYPE_FIELD",
joinColumns = @JoinColumn(name="BULK_UPLOAD_FILE_TYPE_ID", referencedColumnName="BULK_UPLOAD_FILE_TYPE_ID"),
inverseJoinColumns = @JoinColumn(name="BULK_UPLOAD_FILE_FIELD_ID", referencedColumnName="BULK_UPLOAD_FILE_FIELD_ID")
)

I don't mind using the Hibernate-specific annotations since the problem is JPA limitation.

Thanks


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 05, 2009 11:42 am 
Newbie

Joined: Fri Jan 30, 2009 6:31 am
Posts: 13
Location: Bucharest/Romania
I've recently find out that by using Hibernate mapping:

org.hibernate.annotations.CascadeType.DELETE_ORPHAN

changes the fetching type to LAIZY.

So if you have something like:

@OneToMany(fetch=FetchType.DELETE_ORPHAN, cascade=CascadeType.ALL)
@org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)

and you modify an entity like:

main entity with 2 children entities

by removing one child, when you merge the changes the fetch goes to LAIZY.

Hope this helps.

P.S.
I'm still struggling to find a solution on moving fetch=EAGER again as I don't want to manually remove orphan children just for using JPA annotation sake. So if anyone has an idea then please document it.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 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.