JPA CascadeType.ALL tidak menghapus anak yatim


132

Saya mengalami masalah menghapus node yatim menggunakan JPA dengan pemetaan berikut

@OneToMany (cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "owner")
private List<Bikes> bikes;

Saya mengalami masalah peran yatim di sekitar basis data.

Saya dapat menggunakan org.hibernate.annotations.Cascadetag spesifik Hibernate anotasi tapi jelas saya tidak ingin mengikat solusi saya ke dalam implementasi Hibernate.

EDIT : Sepertinya JPA 2.0 akan menyertakan dukungan untuk ini.

Jawaban:


164

Jika Anda menggunakannya dengan Hibernate, Anda harus secara eksplisit mendefinisikan anotasi CascadeType.DELETE_ORPHAN, yang dapat digunakan bersama dengan JPA CascadeType.ALL.

Jika Anda tidak berencana untuk menggunakan Hibernate, Anda harus terlebih dahulu menghapus elemen anak dan kemudian menghapus catatan utama untuk menghindari catatan anak yatim.

urutan eksekusi

  1. ambil baris utama untuk dihapus
  2. ambil elemen anak
  3. hapus semua elemen anak
  4. hapus baris utama
  5. sesi tutup

Dengan JPA 2.0, Anda sekarang dapat menggunakan opsi orphanRemoval = true

@OneToMany(mappedBy="foo", orphanRemoval=true)

3
terima kasih saya akhirnya melalui rute ini, saya pikir ini sedikit oversite untuk spesifikasi JPA.
Paul Whelan

13
Standar JPA 2.0 sekarang memiliki deleteOrphan sebagai atribut untuk @OneToMany. Jika Anda menggunakan hibernate terbaru, Anda dapat melakukan @OneToMany (..., deleteOrphan = true)
jomohke

apa urutan eksekusi ketika saya baru saja memperbarui elemen-anak? akankah catatan anak yatim dihapus?
jAckOdE

113

Jika Anda menggunakan JPA 2.0, sekarang Anda dapat menggunakan orphanRemoval=trueatribut @xxxToManyanotasi untuk menghapus anak yatim.

Sebenarnya, CascadeType.DELETE_ORPHANsudah usang di 3.5.2-Final.


6
Sebenarnya saya pikir orphanRemoval = true berarti sesuatu yang lain, yaitu, menghapus objek ketika saya menghapusnya dari koleksi orang tuanya. Lihat download.oracle.com/javaee/6/tutorial/doc/bnbqa.html#giqxy
Archie

Silakan g melalui tautan Archie.
Jigar Shah

4
orphanRemoval = true juga tidak berfungsi. Itu harus dilakukan dengan cara lama.
Joe Almore

45
╔═════════════╦═════════════════════╦═════════════════════╗
   Action      orphanRemoval=true    CascadeType.ALL   
╠═════════════╬═════════════════════╬═════════════════════╣
   delete         deletes parent      deletes parent   
   parent         and orphans         and orphans      
╠═════════════╬═════════════════════╬═════════════════════╣
   change                                              
  children      deletes orphans         nothing        
    list                                               
╚═════════════╩═════════════════════╩═════════════════════╝

1
Apa yang terjadi jika saya memiliki cascade = CascadeType.ALL, orphanRemoval = falsedan menghapus induknya? Apakah ini akan menghapus anak-anak, meskipun saya sudah secara khusus menyuruh TIDAK melakukannya?
izogfif


7

Anda dapat menggunakan @PrivateOwned untuk menghapus anak yatim misalnya

@OneToMany(mappedBy = "masterData", cascade = {
        CascadeType.ALL })
@PrivateOwned
private List<Data> dataList;

5
Terima kasih @reshma, perlu dicatat @PrivateOwned adalah ekstensi JPA eclipselink.
Paul Whelan

5

Saya hanya menemukan solusi ini tetapi dalam kasus saya itu tidak berhasil:

@OneToMany(cascade = CascadeType.ALL, targetEntity = MyClass.class, mappedBy = "xxx", fetch = FetchType.LAZY, orphanRemoval = true) 

orphanRemoval = true tidak berpengaruh.


1
Saya perlu membersihkan dan membangun sebelum perubahan mulai berlaku.
maralbjo

Wow, saya sudah mencari satu jam mengapa menambahkan CascadeType.ALL di ManyToOne saya tidak menghapus cascading. Dibersihkan dan dibangun dan berfungsi. Terima kasih @maralbjo.
Andrew Mairose


2

Saya memiliki masalah yang sama dan saya bertanya-tanya mengapa kondisi di bawah ini tidak menghapus anak yatim. Daftar hidangan tidak dihapus di Hibernate (5.0.3.Final) ketika saya menjalankan permintaan penghapusan bernama:

@OneToMany(mappedBy = "menuPlan", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Dish> dishes = new ArrayList<>();

Lalu saya ingat bahwa saya tidak boleh menggunakan query delete bernama , tetapi EntityManager. Saat saya menggunakan EntityManager.find(...)metode untuk mengambil entitas dan kemudian EntityManager.remove(...)menghapusnya, piring juga dihapus.


2

Adil @OneToMany(cascade = CascadeType.ALL, mappedBy = "xxx", fetch = FetchType.LAZY, orphanRemoval = true).

Hapus targetEntity = MyClass.class , ini berfungsi dengan baik.



0

Saya menggunakan pemetaan satu ke satu, tetapi anak tidak dihapus JPA memberikan pelanggaran kunci asing

Setelah menggunakan orphanRemoval = true, masalah terselesaikan


@OneToOne (cascade = CascadeType.ALL, orphanRemoval = true) @JoinColumn (name = "CHILD_OID") pribadi Anak anak;
vipin chauhan
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.