2010-01-06 22 views
131

मुझे माता-पिता और एक बच्चे इकाई के बीच एक सरल @OneToMany मैपिंग के साथ समस्या है। सभी अच्छी तरह से काम करते हैं, जब मैं उन्हें संग्रह से हटा देता हूं तो केवल उस बच्चे के रिकॉर्ड हटा दिए जाते हैं।जेपीए वनटोनी बच्चे को हटा नहीं रहा

माता-पिता:

@Entity 
public class Parent { 
    @Id 
    @Column(name = "ID") 
    private Long id; 

    @OneToMany(cascade = {CascadeType.ALL}, mappedBy = "parent") 
    private Set<Child> childs = new HashSet<Child>(); 

... 
} 

बच्चे:

@Entity 
public class Child { 
    @Id 
    @Column(name = "ID") 
    private Long id; 

    @ManyToOne(cascade = CascadeType.ALL) 
    @JoinColumn(name="PARENTID", nullable = false) 
    private Parent parent; 

    ... 
} 

अब मैं हटा सकते हैं और बच्चे सेट से बच्चे हैं, तो यह डेटाबेस से हटा दिया जाता है नहीं है। मैंने child.parent संदर्भ को रद्द करने का प्रयास किया, लेकिन यह भी काम नहीं किया।

इकाइयों का उपयोग वेब अनुप्रयोग में किया जाता है, हटाए गए अजाक्स अनुरोध के हिस्से के रूप में होता है। सहेजे गए बटन दबाए जाने पर मेरे पास हटाए गए बच्चों की एक सूची नहीं है, इसलिए मैं उन्हें पूरी तरह से हटा नहीं सकता।

उत्तर

222

जेपीए का व्यवहार सही है (विनिर्देश के अनुसार): ऑब्जेक्ट्स को हटाया नहीं गया है क्योंकि आपने उन्हें OneToMany संग्रह से हटा दिया है। ऐसे विक्रेता-विशिष्ट एक्सटेंशन हैं जो ऐसा करते हैं लेकिन मूल जेपीए इसके लिए पूरा नहीं करता है।

भाग में ऐसा इसलिए है क्योंकि जेपीए वास्तव में नहीं जानता है कि इसे संग्रह से हटाए गए कुछ को हटा देना चाहिए या नहीं। वस्तु मॉडलिंग शब्दों में, यह रचना और "एकत्रीकरण * के बीच अंतर है।

रचना में, बच्चे इकाई माता-पिता के बिना कोई अस्तित्व नहीं है। इसका एक उत्कृष्ट उदाहरण हाउस और कमरे के बीच है। हाउस हटाएँ और कमरे भी जाना।

एकत्रीकरण संघ का एक हारने तरह है और पाठ्यक्रम और छात्र द्वारा typified है। कोर्स हटाएँ और छात्र अभी भी मौजूद है (शायद अन्य पाठ्यक्रम में)।

तो तुम करने की जरूरत है या तो विक्रेता-विशिष्ट एक्सटेंशन का उपयोग करें इस व्यवहार को बल दें (यदि उपलब्ध हो) या स्पष्ट रूप से बच्चे को हटा दें और इसे माता-पिता के संग्रह से हटा दें।

+0

अच्छा स्पष्टीकरण धन्यवाद। तो यह मुझे डर लगता है। (मैंने पूछने से पहले कुछ खोज/पढ़ाई की, बस सहेजना चाहते हैं)। किसी भी तरह से मैं जेपीए एपीआई और नाइट हाइबरनेट का उपयोग करने के निर्णय को पछतावा करना शुरू कर देता हूं .. मैं चंद्र पटना पॉइंटर का प्रयास करूंगा और हाइबरनेट डिलीट_ऑर्फन कैस्केड प्रकार का उपयोग करूंगा। – bert

+0

मेरे पास इस बारे में एक समान सवाल है। कृपया इस पोस्ट को यहां देखें, कृपया? http://stackoverflow.com/questions/4569857/jsf-how-to-update-the-list-after-delete-an-item-of-that-list –

+59

जेपीए 2.0 के साथ, अब आप विकल्प का उपयोग कर सकते हैं orphanRemoval = सच – itsadok

2

यहां हटाए गए संदर्भ में, कैस्केड का मतलब है कि यदि आप माता-पिता को हटाते हैं तो बच्चों को हटा दिया जाता है। एसोसिएशन नहीं यदि आप अपने जेपीए प्रदाता के रूप में हाइबरनेट का उपयोग कर रहे हैं, तो आप इसे hibernate specific cascade का उपयोग करके कर सकते हैं।

18

के रूप में बताया गया है, यह क्या मैं जेपीए के साथ करना चाहते हैं के लिए संभव नहीं है, इसलिए मैं इस के साथ hibernate.cascade एनोटेशन कार्यरत, जनक वर्ग में प्रासंगिक कोड अब इस तरह दिखता है:

@OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}, mappedBy = "parent") 
@Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, 
      org.hibernate.annotations.CascadeType.DELETE, 
      org.hibernate.annotations.CascadeType.MERGE, 
      org.hibernate.annotations.CascadeType.PERSIST, 
      org.hibernate.annotations.CascadeType.DELETE_ORPHAN}) 
private Set<Child> childs = new HashSet<Child>(); 

मैं 'ऑल' का उपयोग सरल नहीं कर सका क्योंकि इससे माता-पिता भी हटा दिए गए थे।

64

क्लीटस के उत्तर के अलावा, JPA 2.0, दिसंबर 2010 के बाद से अंतिम, @OneToMany एनोटेशन पर orphanRemoval विशेषता प्रस्तुत करता है। अधिक जानकारी के लिए यह blog entry देखें।

ध्यान दें कि चूंकि नमूना अपेक्षाकृत नया है, सभी जेपीए 1 प्रदाता के पास अंतिम जेपीए 2 कार्यान्वयन नहीं है। उदाहरण के लिए, Hibernate 3.5.0-Beta-2 release अभी तक इस विशेषता का समर्थन नहीं करता है।

32

आप इस कोशिश कर सकते हैं:

@OneToOne(orphanRemoval=true) or @OneToMany(orphanRemoval=true)

+2

धन्यवाद। लेकिन सवाल जेपीए से 1 बार वापस आ गया है। और यह विकल्प वापस उपलब्ध नहीं था। – bert

+7

फिर भी जानना अच्छा है, हम में से उन लोगों के लिए जो जेपीए 2 बार में इसके लिए समाधान खोजते हैं :) – alex440

1

आप इस कोशिश कर सकते हैं:

@OneToOne(cascade = CascadeType.REFRESH) 

या

@OneToMany(cascade = CascadeType.REFRESH) 
2
@Entity 
class Employee { 
    @OneToOne(orphanRemoval=true) 
    private Address address; 
} 

here देखें।

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