Karena ini adalah pertanyaan yang sangat umum, saya menulis artikel ini , yang menjadi dasar jawaban ini.
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 ketika EntityManager
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 dengan PostComment
entitas anak:
The comments
koleksi dalam Post
entitas dipetakan sebagai berikut:
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<Comment> comments = new ArrayList<>();
CascadeType.ALL
The cascade
atribut memberitahu penyedia JPA untuk lulus transisi entitas negara dari induk Post
entitas untuk semua PostComment
entitas yang terkandung dalam comments
koleksi.
Jadi, jika Anda menghapus Post
entitas:
Post post = entityManager.find(Post.class, 1L);
assertEquals(2, post.getComments().size());
entityManager.remove(post);
Penyedia JPA akan menghapus PostComment
entitas terlebih dahulu, dan ketika semua entitas anak dihapus, itu akan menghapus Post
entitas juga:
DELETE FROM post_comment WHERE id = 1
DELETE FROM post_comment WHERE id = 2
DELETE FROM post WHERE id = 1
Penghapusan anak yatim
Ketika Anda mengatur orphanRemoval
atribut true
, penyedia JPA akan menjadwalkan remove
operasi ketika entitas anak dihapus dari koleksi.
Jadi, dalam kasus kami,
Post post = entityManager.find(Post.class, 1L);
assertEquals(2, post.getComments().size());
PostComment postComment = post.getComments().get(0);
assertEquals(1L, postComment.getId());
post.getComments().remove(postComment);
Penyedia JPA akan menghapus post_comment
catatan terkait karena PostComment
entitas tidak lagi dirujuk dalam comments
koleksi:
DELETE FROM post_comment WHERE id = 1
HAPUS CASCADE
The ON DELETE CASCADE
didefinisikan di tingkat FK:
ALTER TABLE post_comment
ADD CONSTRAINT fk_post_comment_post_id
FOREIGN KEY (post_id) REFERENCES post
ON DELETE CASCADE;
Setelah Anda melakukannya, jika Anda menghapus satu post
baris:
DELETE FROM post WHERE id = 1
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
dan orphanRemoval
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 .