2011-08-25 20 views
63

tek yönlü@ManyToOne bir ilişkiye sahip olduğumu varsayalım:JPA: tek yönlü çoktan bire ve basamaklı silme

@Entity 
public class Parent implements Serializable { 

    @Id 
    @GeneratedValue 
    private long id; 
} 

@Entity 
public class Child implements Serializable { 

    @Id 
    @GeneratedValue 
    private long id; 

    @ManyToOne 
    @JoinColumn 
    private Parent parent; 
} 

Eğer bir ana P ve C varsa 1 ... C n geri P'ye başvuruyorsa, temiz ve P kaldırıldığında (yani entityManager.remove(P)) C 1 ... C n otomatik olarak kaldırmak için JPA güzel yolu?

Ne aradığım SQL'de ON DELETE CASCADE'a benzer bir işlevselliktir.

+1

Sadece 'Alt öğe' için bir başvuruda bulunsa bile (bu yolla yönlendirme tek yönlüdür) 'Child' Listesini '@OneToMany' eşlemesiyle eklemeniz ve 'Cascade = ALL 'Ebeveyn' özniteliği? JPA'nın, sadece 1 tarafın referansı zor tuttuğunu çözmesi gerektiğini düşünüyorum. – kvDennis

+1

@kvDennis, çok tarafını bir tarafa sıkıca bağlamak istemediğiniz durumlar var. Örneğin. Güvenlik izinlerinin saydam "eklenti" – Bachi

cevap

56

Ebeveynin çocuğu her iki yönde de ilişkilendirmediğiniz sürece, JPA'daki ilişkiler her zaman tek yönlüdür. Basamaklı ÇALIŞTIRMA işlemleri ebeveynlerden çocuğa, ebeveyn ile çocuk arasındaki ilişkiyi gerektirir (sadece tam tersi değil).

Bu nedenle, söz yapmanız gerekir:

  • Ya @ManyToOne çift yönlü ya da tek yönlü @OneToMany için tek yönlü @ManyToOne ilişkiyi değiştirin. Daha sonra REMOVE işlemlerini kademeli olarak atayabilirsiniz, böylece EntityManager.remove üst öğeyi ve çocukları kaldıracaktır. Ebeveyn koleksiyonundaki alt öğe null olarak ayarlandığında, yani herhangi bir üst öğenin koleksiyonunda bulunmadığında çocuğu kaldırmak için, yetim kalan çocukları silmek üzere orphanRemoval değerini de true olarak belirtebilirsiniz. Ya da alt tablodaki yabancı anahtar kısıtlamasını ON DELETE CASCADE olarak belirtin. Kalıcılık içeriğinin yenilenmesi gerektiğinden, EntityManager.remove(parent) numaralı telefonu aradıktan sonra EntityManager.clear()'u çağırmanız gerekecek - çocuk varlıkları veritabanında silindikten sonra kalıcılık bağlamında mevcut olmamalıdır.
+4

olduğu ACL benzeri kurulumlarda, JPA ek açıklamalı No2 yapmanın bir yolu var mı? – user2573153

+2

Hibernate xml eşlemleriyle No2'yi nasıl yaparım? – arg20

+0

cevabı sizinkilerden daha iyi – Enerccio

11

böyle bir çift yönlü ilişki oluşturun:

@Entity 
public class Parent implements Serializable { 

    @Id 
    @GeneratedValue 
    private long id; 

    @OneToMany(mappedBy = "parent", cascade = CascadeType.REMOVE) 
    private Set<Child> children; 
} 
+0

kötü cevap, çift yönlü ilişkiler büyük çocuk kümeleri üzerinde çalışan inanılmaz bir zaman alır – Enerccio

-1

@Cascade (org.hibernate.annotations.CascadeType.DELETE_ORPHAN)

Verilen açıklama benim için çalıştı. Örnek için

: -

 public class Parent{ 
      @Id 
      @GeneratedValue(strategy=GenerationType.AUTO) 
      @Column(name="cct_id") 
      private Integer cct_id; 
      @OneToMany(cascade=CascadeType.REMOVE, fetch=FetchType.EAGER,mappedBy="clinicalCareTeam", orphanRemoval=true) 
      @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN) 
      private List<Child> childs; 
     } 
      public class Child{ 
      @ManyToOne(fetch=FetchType.EAGER) 
      @JoinColumn(name="cct_id") 
      private Parent parent; 
    } 
39

Eğer açıklama @OnDelete kullanabilirsiniz JPA sağlayıcısı olarak hazırda kullanıyorsanız. Bu açıklama, çocukların veritabanına silinmesini sağlayan tetikleme ON DELETE CASCADE ilişkisine ekleyecektir.

Örnek: ebeveyne çocuktan tek yönlü bir ilişki otomatik olarak tüm çocukları kaldırmak için yeterli olan bu çözüm sayesinde

public class Parent { 

     @Id 
     private long id; 

} 


public class Child { 

     @Id 
     private long id; 

     @ManyToOne 
     @OnDelete(action = OnDeleteAction.CASCADE) 
     private Parent parent; 
} 

. Bu çözüm, herhangi bir dinleyici vb. Ihtiyaç duymaz. Ayrıca Ana Sayfa WHERE id = 1 gibi bir sorguyu da çocukları kaldıracaktır.

+0

@ManyToOne tasarımı değiştirmeden mükemmel bir çözüm çünkü JPA korkunç. –

+0

Bu harika bir cevap, bu bir seçenek bile değil, tüm önemli bir özellik – Yoi

+2

Bu şekilde çalışamam ki, hazırda bekletme veya başka daha ayrıntılı bir örnek var mı? – Mardari