Bu çok yaygın bir soru olduğundan, bu cevabın dayandığı bu makaleyi yazdım .
Varlık durumu geçişleri
JPA, varlık durumu geçişlerini INSERT, UPDATE veya DELETE gibi SQL deyimlerine çevirir.
Bir persist
varlık olduğunda , INSERT deyimini EntityManager
otomatik olarak veya el ile temizlendiğinde yürütülecek şekilde zamanlarsınız .
Ne zaman remove
bir varlık, sen Sebat Bağlam sifonu çekildiğinde yürütülecektir DELETE deyimi, zamanlıyorsanız.
Basamaklı varlık devleti geçişleri
Kolaylık sağlamak için JPA, varlık durumu geçişlerini üst varlıklardan alt öğeye geçirmenize olanak tanır.
Dolayısıyla, alt varlık ile Post
bir @OneToMany
ilişkisi olan bir ana öğeniz varsa PostComment
:
Varlıktaki comments
koleksiyon Post
aşağıdaki gibi eşlenir:
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<Comment> comments = new ArrayList<>();
CascadeType.ALL
cascade
Nitelik ebeveyn gelen varlık hal geçişini geçmesine JPA sağlayıcı söyler Post
herkese varlık PostComment
içinde bulunan kişiler comments
koleksiyonunda.
Varlığı kaldırırsanız Post
:
Post post = entityManager.find(Post.class, 1L);
assertEquals(2, post.getComments().size());
entityManager.remove(post);
JPA sağlayıcısı önce PostComment
varlığı kaldıracak ve tüm alt varlıklar silindiğinde Post
varlığı da silecektir :
DELETE FROM post_comment WHERE id = 1
DELETE FROM post_comment WHERE id = 2
DELETE FROM post WHERE id = 1
Yetim kaldırma
orphanRemoval
Özelliği olarak ayarladığınızda, alt varlık koleksiyondan kaldırıldığında true
JPA sağlayıcı bir remove
işlem zamanlayacaktır .
Yani, bizim durumumuzda,
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);
Varlık koleksiyonda artık referans gösterilmediğinden JPA sağlayıcısı ilişkili post_comment
kaydı kaldıracak :PostComment
comments
DELETE FROM post_comment WHERE id = 1
SİLİNDİR SİLME
ON DELETE CASCADE
FK düzeyinde tanımlanır:
ALTER TABLE post_comment
ADD CONSTRAINT fk_post_comment_post_id
FOREIGN KEY (post_id) REFERENCES post
ON DELETE CASCADE;
Bunu yaptıktan sonra bir post
satırı silerseniz :
DELETE FROM post WHERE id = 1
İlişkili tüm post_comment
varlıklar veritabanı motoru tarafından otomatik olarak kaldırılır. Ancak, yanlışlıkla bir kök varlığı silerseniz bu çok tehlikeli bir işlem olabilir.
Sonuç
JPA'nın cascade
ve orphanRemoval
seçeneklerin avantajı, kayıp güncellemeleri önlemek için iyimser kilitlemeden de yararlanabilmenizdir .
JPA basamaklı mekanizmayı kullanırsanız ON DELETE CASCADE
, birden çok düzeyde çok sayıda alt öğe içeren bir kök varlığı kaldırırsanız çok tehlikeli bir işlem olabilecek DDL düzeyi kullanmanız gerekmez .
Bu konu hakkında daha fazla bilgi için bu makaleye göz atın .