2011-08-25 11 views
63

कहें कि मेरे पास unidirectional@ManyToOne संबंध निम्न जैसा है:जेपीए: यूनिडायरेक्शनल कई से एक और कैस्केडिंग डिलीट

@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; 
} 

यदि मेरे पास माता-पिता पी और बच्चे सी 1 है ... सी n पी को संदर्भित करता है, क्या वहां एक साफ है और जेपीए में बच्चों को स्वचालित रूप से हटाने के लिए जेपीए में सुंदर तरीका सी 1 ... सी n जब पी हटा दिया जाता है (यानी entityManager.remove(P))?

जो मैं खोज रहा हूं वह एक कार्यक्षमता है जो SQL में ON DELETE CASCADE जैसा है।

+1

भले ही केवल 'चाइल्ड' के पास 'अभिभावक' का संदर्भ है (इस तरह संदर्भ में एक-दूसरे के संदर्भ में 'बाल' की सूची जोड़ने के लिए समस्याग्रस्त है और 'कैस्केड = ऑल' 'माता-पिता' के लिए विशेषता? मुझे लगता है कि जेपीए को यह हल करना चाहिए कि केवल 1 पक्ष में भी मुश्किल है संदर्भ। – kvDennis

+1

@kvDennis, ऐसे मामले हैं जहां आप एक तरफ कई तरफ कसकर जोड़ना नहीं चाहते हैं। जैसे एसीएल जैसी सेटअप में जहां सुरक्षा अनुमतियां पारदर्शी हैं "एड-ऑन" – Bachi

उत्तर

56

जेपीए में रिश्ते हमेशा एकजुट होते हैं, जब तक आप माता-पिता को दोनों दिशाओं में बच्चे के साथ जोड़ते हैं। माता-पिता से बच्चे को कैस्केडिंग रिमूव ऑपरेशंस को माता-पिता से बच्चे के संबंध में संबंध होना चाहिए (न केवल विपरीत)।

इसलिए यह करने के लिए की आवश्यकता होगी:

  • या तो, एक दो-तरफा @ManyToOne, या एक यूनिडायरेक्शनल @OneToMany को दिशाहीन @ManyToOne संबंध बदल जाते हैं। फिर आप रिमूव ऑपरेशंस को कैस्केड कर सकते हैं ताकि EntityManager.remove माता-पिता और बच्चों को हटा देगा। आप किसी भी अनाथ बच्चों को हटाने के लिए orphanRemoval को भी सत्य के रूप में निर्दिष्ट कर सकते हैं, जब अभिभावक संग्रह में बाल इकाई शून्य पर सेट की जाती है, यानी बच्चे को हटा दें जब यह किसी भी अभिभावक के संग्रह में मौजूद न हो।
  • या, ON DELETE CASCADE के रूप में बच्चे की तालिका में विदेशी कुंजी बाधा निर्दिष्ट करें। EntityManager.remove(parent) पर कॉल करने के बाद आपको EntityManager.clear() को आमंत्रित करने की आवश्यकता होगी क्योंकि दृढ़ता संदर्भ को रीफ्रेश करने की आवश्यकता है - डेटाबेस इकाइयों को डेटाबेस में हटा दिए जाने के बाद दृढ़ता संदर्भ में मौजूद नहीं होना चाहिए।
+4

क्या जेपीए एनोटेशन के साथ नंबर 2 करने का कोई तरीका है? – user2573153

+2

मैं हाइबरनेट xml मैपिंग के साथ No2 कैसे करूं? – arg20

+0

आपके नीचे उत्तर – Enerccio

11

एक दो-तरफा संबंध बनाएं, इस तरह:

@Entity 
public class Parent implements Serializable { 

    @Id 
    @GeneratedValue 
    private long id; 

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

खराब उत्तर से बेहतर तरीका है, जेपीए में द्विपक्षीय संबंध भयानक हैं क्योंकि बड़े बच्चों के सेट पर परिचालन अविश्वसनीय समय लेता है – Enerccio

-1

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

को देखते हुए एनोटेशन मेरे लिए काम किया।

उदाहरण के लिए: -

 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

आप हाइबरनेट अपने जेपीए प्रदाता के रूप में आप एनोटेशन @OnDelete उपयोग कर सकते हैं प्रयोग कर रहे हैं। यह एनोटेशन ट्रिगर रिलेशनशिप को जोड़ देगा CLECADE पर, जो डेटाबेस को बच्चों को हटाने का प्रतिनिधि है।

उदाहरण:

public class Parent { 

     @Id 
     private long id; 

} 


public class Child { 

     @Id 
     private long id; 

     @ManyToOne 
     @OnDelete(action = OnDeleteAction.CASCADE) 
     private Parent parent; 
} 
इस समाधान माता-पिता के लिए बच्चे से एक यूनिडायरेक्शनल संबंध स्वचालित रूप से सभी बच्चों को दूर करने के लिए पर्याप्त है के साथ

। इस समाधान को किसी भी श्रोताओं आदि की आवश्यकता नहीं है। जैसे प्रश्न जैसे माता-पिता से हटाएं आईडी = 1 बच्चों को हटा देगा।

+0

यह @ManyToOne डिज़ाइन को बदले बिना एक सही समाधान है। –

+0

यह एक अच्छा जवाब है, यह एक विकल्प भी नहीं है यह एक पूरी महत्वपूर्ण विशेषता है – Yoi

+2

मैं इसे इस तरह से काम नहीं कर सकता, क्या हाइबरनेट का कोई विशिष्ट संस्करण या इस तरह के अन्य विस्तृत उदाहरण हैं? – Mardari

संबंधित मुद्दे