JPA CascadeType.ALL does not delete orphans

183,446

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

  1. fetch main row to be deleted
  2. fetch child elements
  3. delete all child elements
  4. delete main row
  5. 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;
Share:
183,446
Paul Whelan
Author by

Paul Whelan

Java Developer Linux User

Updated on October 09, 2020

Comments

  • Paul Whelan
    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
    Paul Whelan over 15 years
    thanks I ended up going this route, I think this is a bit of an oversite for the JPA spec.
  • jeremyh
    jeremyh almost 14 years
    The 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
    Archie over 13 years
    Actually 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
    Paul Whelan almost 13 years
    Thanks @reshma it should be noted @PrivateOwned is a eclipselink JPA extension.
  • maralbjo
    maralbjo almost 12 years
    I needed to clean and build before the change came into effect.
  • Jigar Shah
    Jigar Shah almost 12 years
    Please g through Archie's link.
  • Joe Almore
    Joe Almore almost 11 years
    orphanRemoval=true does not work either. It has to be done the old way.
  • jAckOdE
    jAckOdE almost 10 years
    what is execution sequence when i just update child-elements? will orphan-records be deleted?
  • Andrew Mairose
    Andrew Mairose almost 9 years
    Wow, 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
    vipin chauhan over 8 years
    @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true) @JoinColumn(name = "CHILD_OID") private Child child;
  • izogfif
    izogfif about 6 years
    What 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?