2008-10-13 14 views
9

मेरे पास एक इकाई है [प्रोजेक्ट] जिसमें अन्य इकाइयों का संग्रह शामिल है [प्रश्न]।हाइबरनेट हटाएं कैस्केड

मैंने "ऑल-डिलीट-अनाथ" के कैस्केड विशेषता के साथ संबंध मैप किया है।

मेरे डीबी में संबंध प्रश्न तालिका पर प्रोजेक्ट_आईडी (एफके) फ़ील्ड के साथ मैप किया गया है। यह क्षेत्र शून्य नहीं हो सकता क्योंकि मैं किसी परियोजना के बिना कोई प्रश्न नहीं चाहता हूं।

जब मैं session.delete (प्रोजेक्ट) करता हूं तो यह एक अपवाद फेंकता है कि प्रोजेक्ट_आईडी शून्य नहीं हो सकता है, लेकिन अगर मैं उस क्षेत्र में नॉन-अवरुद्ध बाधा को हटा देता हूं, तो हटाना अच्छा काम करता है।

कोई भी इसे हल करने के बारे में जानता है?

+0

आपको शायद अपने मैपिंग के प्रासंगिक हिस्सों को दिखाना चाहिए। मैं गैर-विदेशी विदेशी कुंजी के साथ हर समय सभी डिलीट-अनाथ का उपयोग करता हूं और कभी भी कोई समस्या नहीं होती है। –

उत्तर

-2

डिलीट पहले प्रोजेक्ट पर होता है और प्रश्न के लिए कैस्केडिंग होता है, लेकिन प्रोजेक्ट डिलीट में प्रश्नों में प्रोजेक्ट_आईडी (रेफरेंसियल अखंडता के लिए एक नलिंग शामिल है। आपको प्रश्न ऑब्जेक्ट को हटाने पर अपवाद नहीं मिल रहा है , लेकिन क्योंकि झरना प्रश्न (ओं) में FK शून्य पर कोशिश कर रहा है।

"Java Persistence with Hibernate" को देखते हुए, मुझे लगता है कि आप वास्तव में क्या हटाने की एक झरना प्रकार चाहते हैं या निकाल सकते हैं, को नष्ट-अनाथ नहीं।

+0

यह कुछ भी हल नहीं करता है –

0

एक रणनीति डेटाबेस में विदेशी-कुंजी को ऑन-डिलीट-कैस्केड के साथ चिह्नित करना है, ताकि जैसे ही NHibernate किसी प्रोजेक्ट को हटाने के लिए डेटाबेस को बताए, डेटाबेस स्वयं ही कैस्केड होगा हटाना फिर आपको NHibernate को बताना होगा कि डेटाबेस स्वयं एक कैस्केड हटा देता है।

+0

क्या यह निबर्ननेट 1.2 के साथ सकारात्मक है? –

11

सीधे documentation से। यह आपकी समस्या वास्तव में बताते हैं मुझे विश्वास:

हालांकि, इस कोड

Parent p = (Parent) session.Load(typeof(Parent), pid); 
// Get one child out of the set 
IEnumerator childEnumerator = p.Children.GetEnumerator(); 
childEnumerator.MoveNext(); 
Child c = (Child) childEnumerator.Current; 

p.Children.Remove(c); 
c.Parent = null; 
session.Flush(); 

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

Parent p = (Parent) session.Load(typeof(Parent), pid); 
// Get one child out of the set 
IEnumerator childEnumerator = p.Children.GetEnumerator(); 
childEnumerator.MoveNext(); 
Child c = (Child) childEnumerator.Current; 

p.Children.Remove(c); 
session.Delete(c); 
session.Flush(); 

अब, हमारे मामले में, कोई बच्चा अपने माता-पिता के बिना वास्तव में अस्तित्व में नहीं हो सकता है। इसलिए यदि हम संग्रह से बच्चे को हटा देते हैं, तो हम वास्तव में इसे हटाना चाहते हैं। इसके लिए, हमें cascade = "all-delete-orphan" का उपयोग करना होगा।

<set name="Children" inverse="true" cascade="all-delete-orphan"> 
    <key column="parent_id"/> 
    <one-to-many class="Child"/> 
</set> 

संपादित करें:

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

एक बात नोट करने के लिए है, तो आप अपने हाइबरनेट config में कई-से-एक रिश्ते पर

not-null="true" 

मिला है?

+0

क्षमा करें। यह काम करता है, लेकिन मुझे समझ में नहीं आता क्यों। दस्तावेज़ों से यह कहता है कि जब आप एक बिडरेक्शनल एसोसिएशन (और यह मेरा मामला नहीं है) को मैप करते समय उलटा सच होता है, वैसे भी यह जोड़कर यह अच्छी तरह से काम करता है। धन्यवाद।यदि आप समझते हैं कि क्यों उलटा = सही काम करता है, तो मैं आपका उत्तर स्वीकार करूंगा –

+0

क्या हाइबरनेट दस्तावेज़ों से इसका कोई उदाहरण है? यह मेरे लिए अजीब लगता है कि उसने हाइबरनेट के बारे में पूछा और आपने कुछ निषेध दस्तावेज के साथ उत्तर दिया। – kbaribeau

+0

मैंने आपके लिए कुछ अतिरिक्त जानकारी जोड़ा। खुशी है कि यह आपके लिए काम कर चुका है :) – abarax

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