2011-04-26 15 views
10

मान लीजिए कि हम दो संस्थाओं, एक करते हैं और बी बी ए की तरह करने के लिए एक बहुत-से-एक संबंध नहीं है इस प्रकार है:क्या मुझे जेपीए या डेटाबेस कैस्केड हटाने को देना चाहिए?

@Entity 
public class A { 
    @OneToMany(mappedBy="a_id") 
    private List<B> children; 
} 

@Entity 
public class B { 
    private String data; 
} 

अब, मैं एक वस्तु हटा सकते हैं और करने के लिए हटाए गए झरना करना चाहते हैं सब अपने बच्चे (बी)। ऐसा करने के दो तरीके हैं:

1) cascade=CascadeType.ALL, orphanRemoval=true को OneToMany एनोटेशन में जोड़ें, जेपीए डेटाबेस से ए-ऑब्जेक्ट को हटाने से पहले सभी बच्चों को हटा दें।

2) कक्षाओं को छोड़ दें और बस डेटाबेस को हटाए जाने दें।

क्या बाद के विकल्प का उपयोग करने में कोई समस्या है? क्या यह एंटिटी मैनेजर को पहले से हटाए गए ऑब्जेक्ट्स के संदर्भ रखने का कारण बनता है? विकल्प को दो से अधिक चुनने का मेरा कारण यह है कि विकल्प एक हटाने के लिए एन + 1 एसक्यूएल क्वेरी उत्पन्न करता है, जिसमें ऑब्जेक्ट ए में बहुत सारे बच्चे होते हैं, जबकि विकल्प दो केवल एक ही SQL क्वेरी उत्पन्न करता है और फिर चलता है आनंद से। क्या इसके बारे में कोई "सर्वश्रेष्ठ अभ्यास" है?

उत्तर

6

में मदद करता है EclipseLink में आप उपयोग कर सकते हैं नष्ट कर सकते हैं यदि आप @CascadeOnDelete एनोटेशन का उपयोग करते हैं तो दोनों। EclipseLink भी आपके लिए कैस्केड डीडीएल उत्पन्न करेगा।

देखें, http://wiki.eclipse.org/EclipseLink/Examples/JPA/DeleteCascade

इस डेटाबेस की अनुमति से हटाए जाने का अनुकूलन कर यह कर, लेकिन यह भी वस्तुओं को हटाने के द्वारा कैश और दृढ़ता इकाई बनाए रखता है।

ध्यान दें कि orphanRemoval = true संग्रह से हटाई गई वस्तुओं को भी हटा देगा, जो डेटाबेस कैस्केड बाधा आपके लिए नहीं करेगी, इसलिए जेपीए में नियम अभी भी आवश्यक हैं। कुछ रिश्ते भी हैं जो डेटाबेस को हटाने के लिए संभाल नहीं सकते हैं, क्योंकि डेटाबेस केवल बाधा की विपरीत दिशा में कैस्केड कर सकता है, एक विदेशी कुंजी के साथ OneToOne, या जॉइन टेबल के साथ OneToMany डेटाबेस पर कैस्केड नहीं किया जा सकता है।

+0

लगता है कि मैं क्या देख रहा था! बहुत बुरा यह विक्रेता विशिष्ट है, लेकिन इसे करना होगा। धन्यवाद! –

3

मैं डेटाबेस पसंद करूंगा। क्यूं कर?

  • डेटाबेस शायद बहुत तेजी से इस
  • डेटाबेस कर प्राथमिक जगह अखंडता और संबंध जानकारी धारण करने के लिए होना चाहिए। जेपीए सिर्फ इतना है कि जानकारी
  • को दर्शाती है आप (यानी जेपीए) के बिना एक अलग आवेदन/मंच के साथ कनेक्ट कर रहे हैं, तब भी आप cascadingly अपने रिकॉर्ड है, जो वृद्धि डेटा अखंडता
+0

मैं आपके अंक से सहमत हूं, लेकिन क्या आप सुनिश्चित हैं कि इकाई प्रबंधक को अधिसूचित नहीं किया जाना चाहिए कि कई वस्तुओं को हटा दिया गया है? शायद सबसे बुरी स्थिति परिदृश्य यह है कि कुछ मृत वस्तुओं को कैश किया जाता है (लेकिन आमतौर पर यह सुलभ नहीं होता है क्योंकि यह कुछ मिनटों के लिए हटाए गए मूल वस्तु के माध्यम से होता है)। यदि मैं डेटाबेस में और जेपीए में दोनों को कैस्केड निर्दिष्ट करता हूं तो पॉइंट दो और तीन को अनदेखा किया जा सकता है। आप इस विकल्प के बारे में क्या सोचते हैं? –

+1

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

0

This answer कुछ वास्तव में मजबूत तर्क उठाता है कि यह जेपीए क्यों होना चाहिए जो कि कैस्केड को संभालता है, डेटाबेस नहीं।

यहाँ प्रासंगिक उद्धरण है:

... यदि आप डेटाबेस पर cascades बनाना होगा, और उन्हें हाइबरनेट (प्रदर्शन के मुद्दों के लिए) में की घोषणा नहीं आप में कुछ परिस्थितियों त्रुटियों मिल सकता है। ऐसा इसलिए है क्योंकि हाइबरनेट अपने सत्र कैश में इकाइयों को स्टोर करता है, इसलिए यह कैस्केड में कुछ हटाने वाले डेटाबेस के बारे में नहीं पता होगा।

आप दूसरे स्तर कैश का उपयोग करते हैं, अपनी स्थिति, और भी बदतर है, क्योंकि इस कैश सत्र और db-साइड पर इस तरह के बदलाव से अधिक समय रहता है अन्य सत्र के रूप में लंबे समय के पुराने मूल्यों इस कैश में जमा हो जाती है के लिए अदृश्य हो जाएगा ।

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

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