@ManyToOne JPA derneği için CascadeType.ALL'nin anlamı nedir


210

Sanırım bir @ManyToOneilişki bağlamında basamaklı olmanın anlamını yanlış anladım .

Dava:

public class User {

   @OneToMany(fetch = FetchType.EAGER)
   protected Set<Address> userAddresses;

}

public class Address {

   @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
   protected User addressOwner;

}

Bunun anlamı nedir cascade = CascadeType.ALL? Örneğin, veritabanından belirli bir adresi silersem, eklediğim gerçeği cascade = CascadeType.ALLverilerimi nasıl etkiler ( Usersanırım)?

Yanıtlar:


360

Bunun anlamı CascadeType.ALL, kalıcılığın tüm EntityManagerişlemleri ( PERSIST, REMOVE, REFRESH, MERGE, DETACH) ilgili varlıklara yayacağı (art arda sıralayacağı) .

Sizin durumunuzda kötü bir fikir gibi görünüyor, çünkü bir kaldırma işlemi Addressilgili olanın kaldırılmasına yol açacaktır User. Bir kullanıcının birden fazla adresi olabileceğinden, diğer adresler yetim olur. Bununla birlikte, ters durum (açıklayıcı not User) mantıklı olacaktır - bir adres yalnızca tek bir kullanıcıya aitse, bu kullanıcı silinirse bir kullanıcıya ait tüm adreslerin kaldırılmasını sağlamak güvenlidir.

BTW: Katılma sütununun ADRES tablosunda olması gerektiğine dair kalıcılık sağlayıcısına sinyal göndermek için bir mappedBy="addressOwner"öznitelik eklemek isteyebilirsiniz User.


55
Mapped'in en iyi ve en kısa açıklaması için +1
Eylül'de Ridcully

4
@OneToMany tarafında CascadeType.ALL olsa iyi olabilir.
mvmn

48

OpenJPA belgelerinden bir örnek için buraya bakın . CascadeType.ALLtüm eylemleri gerçekleştireceği anlamına gelir.

Alıntı:

CascadeType.PERSIST: Bir varlığa devam ederken, kendi alanlarında tutulan varlıkları da devam ettirir. EntityManager, yıkama sırasında yeni bir varlığa başvuran bir alan bulursa ve alan CascadeType.PERSIST'i kullanmazsa, bu basamaklı kuralın liberal bir uygulamasını öneririz.

CascadeType.REMOVE: Bir varlığı silerken, bu alanda tutulan varlıkları da siler.

CascadeType.REFRESH: Bir varlığı yenilerken, bu alanda tutulan varlıkları da yenileyin.

CascadeType.MERGE: Varlık durumunu birleştirirken, bu alanda tutulan varlıkları da birleştirin.

Sebastian


4
JPA'da yeni olan bu bilgiler yararlıdır, ya da Detach burada?
Sarz

1
CascadeType.DETACH öğesinde, bir varlığı sökerken, üst varlık tarafından tutulan varlıkları da siler.
Dorian Mejer

29

Ben açıklandığı gibi bu makalede ve benim kitap, Yüksek Performanslı Java Sebat , kullanmak olmamalıdır CascadeType.ALLüzerinde @ManyToOneberi varlık devlet geçişler Çocuk olanlar, tersi değil yol Veli kurumlardan yaymak gerekir.

@ManyToOneAltta yatan Yabancı anahtar sütununu beri yan daima Çocuk kuruluşudur.

Bu nedenle, hareket etmeliyiz CascadeType.ALLgelen @ManyToOnedernek @OneToManyda kullanması gereken tarafı, mappedByo beri niteliğini en verimli bire birçok tablo ilişkisi haritalama .


18

EJB3.0 Spesifikasyonundan :

Kademeli ek açıklama öğesinin kullanımı, bir işlemin etkisini ilişkili varlıklara yaymak için kullanılabilir. Basamaklı işlevsellik en çok ebeveyn-çocuk ilişkilerinde kullanılır.

X yönetilen bir varlıksa, kaldırma işlemi onun kaldırılmasına neden olur. X'ten bu diğer varlıklara olan ilişkiler cascade = REMOVE veya cascade = ALL ek açıklama öğesi değeri ile açıklanırsa, kaldırma işlemi X tarafından başvurulan varlıklara basamaklandırılır.

Kısaca, ile tanımlanan varlık ilişkileri CascadeType.All, ebeveyn üzerinde meydana gelen kalıcılık, yenileme, birleştirme ve kaldırma gibi tüm kalıcılık olaylarının çocuğa aktarılmasını sağlayacaktır. Diğer CascadeTypeseçenekleri tanımlamak , geliştiriciye varlık birliğinin kalıcılığı nasıl ele alacağı konusunda daha ayrıntılı bir denetim düzeyi sağlar.

Örneğin, bir Sayfa Listesi içeren bir nesne Kitabım olsaydı ve bu listeye bir sayfa nesnesi eklersem. Eğer @OneToManyKitap ve Sayfa arasındaki ilişkiyi tanımlayan açıklama olarak işaretlenmiş CascadeType.AllSayfa sonuçlanacak Kitabı devam eden, aynı zamanda veritabanına kalıcı olmak.


11

JPA 2.0'da, bir adresi bir Kullanıcı varlığından kaldırdıysanız silmek isterseniz, adresinize orphanRemoval=true(yerine CascadeType.REMOVE) ekleyebilirsiniz @OneToMany.

Arasında daha fazla açıklama orphanRemoval=trueve CascadeType.REMOVEolduğu burada .


4

Yalnızca kullanıcıya atanan adresi silmek ve Kullanıcı varlık sınıfını etkilememek istiyorsanız, şöyle bir şey denemelisiniz:

@Entity
public class User {
   @OneToMany(mappedBy = "addressOwner", cascade = CascadeType.ALL)
   protected Set<Address> userAddresses = new HashSet<>();
}

@Entity 
public class Addresses {
   @ManyToOne(cascade = CascadeType.REFRESH) @JoinColumn(name = "user_id")
   protected User addressOwner;
}

Bu şekilde, ek açıklamalarda getirmeyi kullanma konusunda endişelenmenize gerek yoktur. Ancak Kullanıcıyı silerken, bağlı adresi kullanıcı nesnesine de sileceğinizi unutmayın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.