2015-06-23 5 views
6

महत्वपूर्ण सूचना: आप इस पोस्ट पढ़ रहे हैं, तो में गहराई से विचार विमर्श के लिए भी this post में देख पर विचार करें।सत्य पर orphanRemoval स्थापना एक और माता-पिता को अपने अभिभावकों से बच्चों पलायन जबकि


यह एक काफी सामान्य व्यवहार/स्थिति/आवश्यकता जहां एक माता पिता के बच्चों को एक और माता पिता के लिए चले जा सकता है। क्या होता है, यदि orphanRemoval ऐसे रिश्तों के विपरीत पक्ष पर true पर सेट है?

उदाहरण के रूप में विचार करें, निम्नानुसार एक से अधिक सरल संबंध हैं।

उलटा पक्ष (विभाग):

@OneToMany(mappedBy = "department", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true) 
private List<Employee> employeeList = new ArrayList<Employee>(0); 

मालिक पक्ष (कर्मचारी):

@JoinColumn(name = "department_id", referencedColumnName = "department_id") 
@ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.DETACH}) 
private Department department; 

जबकि तरह निम्नलिखित (जहां department एक ग्राहक द्वारा आपूर्ति की एक अलग इकाई है एक ऑपरेशन/कार्रवाई विलय),

Employee employee = entityManager.find(Employee.class, 1L); 
Department newDepartment = entityManager.contains(department) ? department : entityManager.merge(department); 

if (!newDepartment.equals(employee.getDepartment())) { 
    employee.getDepartment().getEmployeeList().remove(employee); 
    // Since orphanRemoval is set to true, 
    // this should cause a row from the database table to be removed inadvertently 
    // by issuing an addition DELETE DML statement. 
} 

employee.setDepartment(newDepartment); 
employee.setEmployeeName("xyz");   

List<Employee> employeeList = newDepartment.getEmployeeList(); 

if (!employeeList.contains(employee)) { 
    employeeList.add(employee); 
} 

entityManager.merge(employee); 

बेशक , एक जोड़ने किसी संस्था को हटाने से संबंधित संस्थाओं में रक्षात्मक लिंक (रिलेशनशिप) प्रबंधन विधियों का उपयोग करके बेहतर किया जा सकता है।

एक ग्राहक द्वारा एक विभाग उदाहरण प्रदान किया जाता है। यह एक अलग इकाई है। प्रश्न में ग्राहक द्वारा किए गए प्रशासनिक कार्रवाई के आधार पर यह वही या अलग विभाग हो सकता है। नतीजतन, यदि ग्राहक द्वारा प्रदान किया गया विभाग उदाहरण वर्तमान Employee द्वारा आयोजित एक से अलग है, तो इसे मौजूदा पुराने विभाग द्वारा आयोजित विपरीत पक्ष पर आयोजित कर्मचारियों (employeeList) की सूची से पहले हटा दिया जाना चाहिए नए department द्वारा आयोजित कर्मचारियों की सूची में जोड़ने से पहले Employee के साथ। वर्ष विभाग (इससे पहले कि यह कार्रवाई शुरू हो गई है) यानी जबकि पलायन -

एक अनुमान के रूप में, Employee पंक्ति जबकि कर्मचारियों वर्तमान में कर्मचारी के विभाग द्वारा करने के लिए भेजा जा रहा है की सूची से Employee उदाहरण को हटाने डेटाबेस से अनजाने में हटा दिया जाना चाहिए अपने माता-पिता से दूसरे माता-पिता के बच्चे को, किसी अन्य माता-पिता द्वारा अपनाया जाने से पहले बच्चे को अपने मूल माता-पिता से हटा दिया जाना चाहिए और उस बच्चे की पंक्ति डेटाबेस से अनजाने में हटा दी जानी चाहिए (orphanRemoval = true)।

डेटाबेस तालिका में कर्मचारी पंक्ति, अद्यतन कॉलम मानों के साथ बरकरार है। UPDATE कथन को छोड़कर कोई डीएमएल बयान उत्पन्न नहीं होता है।

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

वर्तमान में जेपीए 2.1 युक्त एक्लिप्ससेंक 2.6.0 का उपयोग कर रहा है।


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

एक Employee इकाई केवल नष्ट कर दिया जाता है, तो (इस प्रकार, नहीं सूची में जोड़ा बाद इसे हटा दिया गया था - एक और माता पिता के लिए चले नहीं लेकिन सिर्फ हटाए गए) सूची से उलटा पर पक्ष, फिर इसकी संबंधित पंक्ति डेटाबेस से भी सामान्य रूप से हटा दी जाती है (orphanRemoval = true) लेकिन पंक्ति को बस अपडेट किया जाता है, जब Employee इकाई (बच्चे) को किसी मूल अभिभावक की सूची में हटा दिया जाता है, तो उसके मूल अभिभावक की सूची से हटा दिया जाता है (इकाई का प्रवासन)।

प्रदाता अपने माता-पिता से दूसरे माता-पिता को अपडेट के रूप में पहचानने के लिए पर्याप्त स्मार्ट प्रतीत होता है।

व्यवहार को हाइबरनेट (4.3.6 फ़ाइनल) और एक्लिप्ससेंक (2.6.0) दोनों पर समान देखा जा सकता है लेकिन यदि यह एक प्रदाता विशिष्ट व्यवहार (पोर्टेबल नहीं) पर निर्भर नहीं किया जा सकता है। मुझे जेपीए स्पेक में इस व्यवहार के बारे में कुछ भी नहीं मिला।

उत्तर

3

यह JPA specification में प्रलेखित है।

धारा 3.2.4 (अंश):

फ्लश आपरेशन के अर्थ विज्ञान, एक इकाई एक्स के लिए आवेदन किया इस प्रकार हैं:

  • हैं एक्स एक प्रबंधित इकाई है, यह डेटाबेस में सिंक्रनाइज़ किया गया है।
    • सभी संस्थाओं वाई एक्स से एक रिश्ता द्वारा संदर्भित के लिए, यदि वाई के संबंध झरना तत्व मूल्य के साथ एनोटेट कर दिया गया है झरना = जारी रहती है या झरना = सभी, जारी रहती आपरेशन वाई
    • को
  • लागू किया जाता है

धारा 3.2.2 (अंश):

जारी रहती है के शब्दों ओ peration, एक इकाई एक्स के रूप में कर रहे हैं के लिए लागू इस प्रकार है:

  • तो एक्स निकाली गई इकाई है, यह कामयाब हो जाता है।

orphanRemoval JPA javadoc:

(वैकल्पिक) करना है या नहीं संस्थाओं कि रिश्ते से हटा दिया गया है करने के लिए निकालें 'संचालन लागू करते हैं और उन संस्थाओं को निकालने आपरेशन झरना।

orphanRemoval Hibernate docs:

एक इकाई एक @OneToMany संग्रह से निकाल दिया जाता है या एक संबद्ध इकाई एक @OneToOne संघ से dereferenced है, तो यह संबद्ध इकाई विलोपन के लिए चिह्नित किया जा सकता है, तो orphanRemoval है true पर सेट करें।

तो, आप विभाग D1 से कर्मचारी E हटाने और उसके विभाग D2 में जोड़ें।

हाइबरनेट डेटाबेस के साथ D1 विभाग को सिंक्रनाइज़ करता है, यह देखता है कि E कर्मचारियों की सूची में नहीं है और E हटाने के लिए अंक हैं। फिर यह D2 को डेटाबेस और कैस्केड PERSIST कर्मचारियों के साथ ऑपरेशन (अनुभाग 3.2.4) के साथ सिंक्रनाइज़ करता है। चूंकि E अब इस सूची में है, कैस्केड इस पर लागू होता है और हाइबरनेट हटाए गए ऑपरेशन को अन-शेड्यूल करता है (खंड 3.2.2)।

साथ ही आप इस question को देखने के लिए चाहते हो सकता है।

"क्या होता है, अगर orphanRemovaltrue पर ऐसे रिश्तों के विपरीत पक्ष पर सेट किया गया है?"

आप इसे पहले से ही विपरीत दिशा में सेट कर चुके हैं (विपरीत पक्ष वह है जो mappedBy घोषित करता है)। तुम्हारा मतलब क्या है अगर यह अन्य पक्ष (इस मामले में @ManyToOne) लगा दी गई है, तो यह कोई मतलब नहीं होगा और यही कारण है कि वहाँ @ManyToOne और @ManyToMany में ऐसी कोई एक विशेषता है।

+0

मुझे आश्चर्य है कि विनिर्देश और लिंक किए गए प्रश्न मूल पोस्ट से संबंधित हैं जो कि उनके माता-पिता से दूसरे माता-पिता से बाल वस्तुओं के प्रवासन के बारे में है। – Tiny

+0

@Tiny कृपया मेरा संपादित उत्तर देखें। उम्मीद है कि, अब मैं और अधिक स्पष्ट हो गया हूं। –

+0

धन्यवाद। तो क्या हम निष्कर्ष निकाल सकते हैं कि यह एक जेपीए-विशिष्ट और प्रदाता-स्वतंत्र, दस्तावेज व्यवहार है? इस प्रकार, यह प्रदाता-विशिष्ट व्यवहार नहीं है। (स्वामित्व वाले पक्ष ('कर्मचारी ') पर कैस्केड यानी' कैस्केड = {कैस्केड टाइप टाइपर्स, कैस्केड टाइप। एमईआरजीई, कैस्केड टाइप .REFRESH, कैस्केड टाइप। डीईटीएचक} 'केवल सजावट के लिए जोड़ा गया है। अगर व्यवहार में हटाया जाता है तो इससे व्यवहार में कोई फर्क नहीं पड़ता पूरी तरह से, वैसे)। – Tiny

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