JPA CascadeType.ALL does not delete orphans
Solution 1
If you are using it with Hibernate, you'll have to explicitly define the annotation CascadeType.DELETE_ORPHAN
, which can be used in conjunction with JPA CascadeType.ALL
.
If you don't plan to use Hibernate, you'll have to explicitly first delete the child elements and then delete the main record to avoid any orphan records.
execution sequence
- fetch main row to be deleted
- fetch child elements
- delete all child elements
- delete main row
- close session
With JPA 2.0, you can now use the option orphanRemoval = true
@OneToMany(mappedBy="foo", orphanRemoval=true)
Solution 2
If you are using JPA 2.0, you can now use the orphanRemoval=true
attribute of the @xxxToMany
annotation to remove orphans.
Actually, CascadeType.DELETE_ORPHAN
has been deprecated in 3.5.2-Final.
Solution 3
╔═════════════╦═════════════════════╦═════════════════════╗
║ Action ║ orphanRemoval=true ║ CascadeType.ALL ║
╠═════════════╬═════════════════════╬═════════════════════╣
║ delete ║ deletes parent ║ deletes parent ║
║ parent ║ and orphans ║ and orphans ║
╠═════════════╬═════════════════════╬═════════════════════╣
║ change ║ ║ ║
║ children ║ deletes orphans ║ nothing ║
║ list ║ ║ ║
╚═════════════╩═════════════════════╩═════════════════════╝
Solution 4
If you are using JPA with EclipseLink, you'll have to set the @PrivateOwned annotation.
Documentation: Eclipse Wiki - Using EclipseLink JPA Extensions - Chapter 1.4 How to Use the @PrivateOwned Annotation
Solution 5
you can use @PrivateOwned to delete orphans e.g
@OneToMany(mappedBy = "masterData", cascade = {
CascadeType.ALL })
@PrivateOwned
private List<Data> dataList;
Comments
-
Paul Whelan over 3 years
I am having trouble deleting orphan nodes using JPA with the following mapping
@OneToMany (cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "owner") private List<Bikes> bikes;
I am having the issue of the orphaned roles hanging around the database.
I can use the annotation
org.hibernate.annotations.Cascade
Hibernate specific tag but obviously I don't want to tie my solution into a Hibernate implementation.EDIT: It seems JPA 2.0 will include support for this.
-
Paul Whelan over 15 yearsthanks I ended up going this route, I think this is a bit of an oversite for the JPA spec.
-
jeremyh almost 14 yearsThe JPA 2.0 standard now has deleteOrphan as an attribute to @OneToMany If you are using the latest hibernate you can do @OneToMany(..., deleteOrphan=true)
-
Archie over 13 yearsActually I think orphanRemoval=true means something else, i.e., delete an object when I remove it from it's parent's collection. See download.oracle.com/javaee/6/tutorial/doc/bnbqa.html#giqxy
-
Paul Whelan almost 13 yearsThanks @reshma it should be noted @PrivateOwned is a eclipselink JPA extension.
-
maralbjo almost 12 yearsI needed to clean and build before the change came into effect.
-
Jigar Shah almost 12 yearsPlease g through Archie's link.
-
Joe Almore almost 11 yearsorphanRemoval=true does not work either. It has to be done the old way.
-
jAckOdE almost 10 yearswhat is execution sequence when i just update child-elements? will orphan-records be deleted?
-
Andrew Mairose almost 9 yearsWow, I've been looking for an hour as to why adding CascadeType.ALL on my ManyToOne wasn't cascading deletes. Cleaned and built and it works. Thanks @maralbjo.
-
vipin chauhan over 8 years@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true) @JoinColumn(name = "CHILD_OID") private Child child;
-
izogfif about 6 yearsWhat happens if I have
cascade = CascadeType.ALL, orphanRemoval = false
and delete the parent? Will it delete children, even though I've specifically told NOT to?