Saya sedikit bingung tentang orphanRemoval
atribut JPA 2.0 .
Saya pikir saya bisa melihatnya diperlukan ketika saya menggunakan alat generasi DB penyedia JPA saya untuk membuat database yang mendasari DDL untuk memiliki ON DELETE CASCADE
hubungan khusus.
Namun, jika DB ada dan sudah memiliki ON DELETE CASCADE
hubungan, apakah ini tidak cukup untuk menghapus penghapusan secara tepat? Apa yang orphanRemoval
dilakukan selainnya?
Bersulang
sumber
Contoh diambil di sini :
Ketika
Employee
objek entitas dihapus, operasi penghapusan akan mengalir keAddress
objek entitas yang direferensikan . Dalam hal ini,orphanRemoval=true
dancascade=CascadeType.REMOVE
identik, dan jikaorphanRemoval=true
ditentukan,CascadeType.REMOVE
berlebihan.Perbedaan antara kedua pengaturan ini adalah pada respons untuk memutuskan hubungan. Misalnya, seperti ketika mengatur bidang alamat ke
null
atau keAddress
objek lain .Jika
orphanRemoval=true
ditentukan,Address
instance terputus akan dihapus secara otomatis. Ini berguna untuk membersihkan objek dependen (mis.Address
) Yang seharusnya tidak ada tanpa referensi dari objek pemilik (misEmployee
.).Jika hanya
cascade=CascadeType.REMOVE
ditentukan, tidak ada tindakan otomatis yang diambil karena memutuskan hubungan bukanlah operasi penghapusan.Untuk menghindari menggantung referensi sebagai akibat dari penghapusan anak yatim, fitur ini hanya boleh diaktifkan untuk bidang yang menampung benda-benda yang tidak dibagi bersama pribadi.
Saya harap ini membuatnya lebih jelas.
sumber
Saat Anda menghapus entitas anak dari koleksi Anda juga akan menghapus entitas anak dari DB juga. orphanRemoval juga menyiratkan bahwa Anda tidak dapat mengubah orang tua; jika ada departemen yang memiliki karyawan, begitu Anda memindahkan karyawan itu ke deparment lain, Anda akan secara tidak sengaja memindahkan karyawan tersebut dari DB di flush / commit (mana yang lebih dulu). Moralnya adalah untuk menetapkan OrphanRemoval menjadi true selama Anda yakin bahwa anak-anak dari orang tua itu tidak akan bermigrasi ke orang tua yang berbeda sepanjang keberadaan mereka. Mengaktifkan orphanRemoval juga secara otomatis menambahkan HAPUS ke daftar kaskade.
sumber
department.remove(emp);
karyawan itu akan dihapus dari tabel emp bahkan tanpa meneleponcommit()
Pemetaan JPA yang setara untuk DDL
ON DELETE CASCADE
adalahcascade=CascadeType.REMOVE
. Penghapusan anak yatim berarti bahwa entitas dependen dihapus ketika hubungan dengan entitas "induk" mereka dihancurkan. Misalnya jika seorang anak dihapus dari suatu@OneToMany
hubungan tanpa secara eksplisit menghapusnya di manajer entitas.sumber
cascade=CascadeType.REMOVE
TIDAK setara denganON DELETE CASCADE
. Pada jangan hapus dalam kode aplikasi dan tidak mempengaruhi pada DDL, lainnya dijalankan dalam DB. Lihat stackoverflow.com/a/19696859/548473Perbedaannya adalah:
- orphanRemoval = true: entitas "Child" dihapus ketika tidak lagi direferensikan (induknya mungkin tidak dihapus).
- CascadeType.REMOVE: "Child" entitas dihapus hanya ketika "Induknya" dihapus.
sumber
Transisi status entitas
JPA menerjemahkan transisi status entitas ke pernyataan SQL, seperti INSERT, UPDATE atau DELETE.
Ketika Anda
persist
suatu entitas, Anda menjadwalkan pernyataan INSERT untuk dieksekusi ketikaEntityManager
memerah, baik secara otomatis atau manual.ketika Anda
remove
suatu entitas, Anda menjadwalkan pernyataan DELETE, yang akan dieksekusi ketika Konteks Persistence memerah.Transisi status entitas Cascading
Untuk kenyamanan, JPA memungkinkan Anda untuk menyebarkan transisi status entitas dari entitas induk ke entitas anak.
Jadi, jika Anda memiliki
Post
entitas induk yang memiliki@OneToMany
kaitan denganPostComment
entitas anak:The
comments
koleksi dalamPost
entitas dipetakan sebagai berikut:CascadeType.ALL
The
cascade
atribut memberitahu penyedia JPA untuk lulus transisi entitas negara dari indukPost
entitas untuk semuaPostComment
entitas yang terkandung dalamcomments
koleksi.Jadi, jika Anda menghapus
Post
entitas:Penyedia JPA akan menghapus
PostComment
entitas terlebih dahulu, dan ketika semua entitas anak dihapus, itu akan menghapusPost
entitas juga:Penghapusan anak yatim
Ketika Anda mengatur
orphanRemoval
atributtrue
, penyedia JPA akan menjadwalkanremove
operasi ketika entitas anak dihapus dari koleksi.Jadi, dalam kasus kami,
Penyedia JPA akan menghapus
post_comment
catatan terkait karenaPostComment
entitas tidak lagi dirujuk dalamcomments
koleksi:HAPUS CASCADE
The
ON DELETE CASCADE
didefinisikan di tingkat FK:Setelah Anda melakukannya, jika Anda menghapus satu
post
baris:Semua
post_comment
entitas yang terkait dihapus secara otomatis oleh mesin database. Namun, ini bisa menjadi operasi yang sangat berbahaya jika Anda menghapus entitas root karena kesalahan.Kesimpulan
Keuntungan dari JPA
cascade
danorphanRemoval
opsi adalah Anda juga dapat memanfaatkan penguncian optimis untuk mencegah pembaruan yang hilang .Jika Anda menggunakan mekanisme cascading JPA, Anda tidak perlu menggunakan level DDL
ON DELETE CASCADE
, yang bisa menjadi operasi yang sangat berbahaya jika Anda menghapus entitas root yang memiliki banyak entitas anak di beberapa level.Untuk detail lebih lanjut tentang topik ini, lihat artikel ini .
sumber
CascadeType
. Ini mekanisme yang saling melengkapi. Sekarang, Anda salah mengira penghapusan tetap ada. Penghapusan anak yatim adalah tentang menghapus asosiasi yang tidak direferensikan sementara yang bertahan adalah tentang menyelamatkan entitas baru. Anda perlu mengikuti tautan yang disediakan dalam jawaban untuk mendapatkan pemahaman yang lebih baik tentang konsep-konsep ini.@GaryK jawaban benar-benar hebat, saya telah menghabiskan satu jam mencari penjelasan
orphanRemoval = true
vsCascadeType.REMOVE
dan itu membantu saya mengerti.Ringkasnya:
orphanRemoval = true
berfungsi sama denganCascadeType.REMOVE
HANYA JIKA kita menghapus objek (entityManager.delete(object)
) dan kami ingin objek childs juga dihapus.Dalam sitiuation yang sama sekali berbeda, ketika kita mengambil beberapa data seperti
List<Child> childs = object.getChilds()
dan kemudian menghapus child (entityManager.remove(childs.get(0)
) menggunakanorphanRemoval=true
akan menyebabkan entitas yang sesuai dengan ituchilds.get(0)
akan dihapus dari database.sumber
penghapusan anak yatim memiliki efek yang sama seperti ON DELETE CASCADE dalam skenario berikut: - Katakanlah kita memiliki hubungan banyak ke satu yang sederhana antara entitas siswa dan entitas panduan, di mana banyak siswa dapat dipetakan ke panduan yang sama dan dalam database kami memiliki hubungan kunci asing antara tabel Student and Guide sehingga tabel student memiliki id_guide sebagai FK.
// Entitas induk
Dalam skenario ini, hubungannya adalah sedemikian rupa sehingga entitas siswa adalah pemilik dari hubungan dan dengan demikian kita perlu menyelamatkan entitas siswa untuk mempertahankan seluruh objek grafik misalnya
Di sini kita memetakan panduan yang sama dengan dua objek siswa yang berbeda dan karena CASCADE.PERSIST digunakan, grafik objek akan disimpan seperti di bawah ini dalam tabel database (MySql dalam kasus saya)
Tabel MAHASISWA: -
Nama ID Dept Id_Guide
1 Roy ECE 1
2 Nick ECE 1
Tabel PANDUAN: -
Gaji ID NAMA
1 Yohanes $ 1500
dan Sekarang jika saya ingin menghapus salah satu siswa, gunakan
dan ketika catatan siswa dihapus, catatan panduan terkait juga harus dihapus, di situlah atribut CASCADE.REMOVE dalam entitas Siswa muncul dalam gambar dan apa yang dilakukan adalah, menghapus siswa dengan pengenal 1 serta objek panduan yang sesuai (pengidentifikasi 1). Tetapi dalam contoh ini, ada satu objek siswa lagi yang dipetakan ke catatan panduan yang sama dan kecuali jika kita menggunakan atribut orphanRemoval = true dalam Entitas Pemandu, kode hapus di atas tidak akan berfungsi.
sumber