यूनिडायरेक्शनल और बिडायरेक्शनल जेपीए और हाइबरनेट संघों के बीच अंतर क्या है?


135

यूनिडायरेक्शनल और बिडायरेक्शनल एसोसिएशन के बीच अंतर क्या है?

चूंकि db में जनरेट की गई तालिका सभी समान हैं, इसलिए मैंने केवल यही पाया है कि बिडिओरेक्शनल एसोसियेशन के प्रत्येक पक्ष में दूसरे का संदर्भ होगा, और यूनिडायरेक्शनल का नहीं।

यह एक यूनिडायरेक्शनल एसोसिएशन है

public class User {
    private int     id;
    private String  name;
    @ManyToOne
    @JoinColumn(
            name = "groupId")
    private Group   group;
}

public class Group {
    private int     id;
    private String  name;
}

द्विदिश संघ

public class User {
    private int     id;
    private String  name;
    @ManyToOne
    @JoinColumn(
            name = "groupId")
    private Group   group;
}
public class Group {
    private int         id;
    private String      name;
    @OneToMany(mappedBy="group")
    private List<User>  users;
}

अंतर यह है कि क्या समूह उपयोगकर्ता का संदर्भ रखता है।

तो मुझे आश्चर्य है कि क्या यह एकमात्र अंतर है? जो अनुशंसित है


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

5
जब यह अद्यतन करने की बात आती है तो द्विदिश संबंध मेरे लिए अराजकता बन गए। :)
diyoda_

जवाबों:


152

मुख्य अंतर यह है कि द्विदिश संबंध दोनों दिशाओं में नेविगेशनल पहुंच प्रदान करता है, ताकि आप स्पष्ट प्रश्नों के बिना दूसरे पक्ष तक पहुंच सकें। इसके अलावा यह आपको दोनों दिशाओं में कैस्केडिंग विकल्प लागू करने की अनुमति देता है।

ध्यान दें कि नेविगेशनल एक्सेस हमेशा अच्छा नहीं होता है, खासकर "एक-से-बहुत-बहुत" और "कई-से-बहुत-बहुत" रिश्तों के लिए। कल्पना कीजिए Groupकि जिसमें हजारों शामिल हैं User:

  • आप उन्हें कैसे एक्सेस करेंगे? बहुत सारे Users के साथ, आपको आमतौर पर कुछ फ़िल्टरिंग और / या पेजिंग लागू करने की आवश्यकता होती है, ताकि आपको किसी भी तरह से क्वेरी निष्पादित करने की आवश्यकता हो (जब तक कि आप संग्रह फ़िल्टरिंग का उपयोग न करें , जो मेरे लिए हैक की तरह दिखता है)। कुछ डेवलपर्स ऐसे मामलों में मेमोरी में फ़िल्टरिंग लागू कर सकते हैं, जो स्पष्ट रूप से प्रदर्शन के लिए अच्छा नहीं है। ध्यान दें कि इस तरह के संबंध होने से इस तरह के डेवलपर्स को प्रदर्शन निहितार्थों पर विचार किए बिना इसका उपयोग करने के लिए प्रोत्साहित किया जा सकता है।

  • आप नए Users को कैसे जोड़ेंगे Group? सौभाग्य से, हाइबरनेट रिश्ते को जारी रखने के पक्ष में दिखता है, इसलिए आप केवल सेट कर सकते हैं User.group। हालाँकि, यदि आप ऑब्जेक्ट को मेमोरी में रखना चाहते हैं, तो आपको भी जोड़ना Userहोगा Group.users। लेकिन यह Group.usersडेटाबेस से सभी तत्वों को लाने के लिए हाइबरनेट करेगा !

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

यह सभी देखें:


नमस्ते, धन्यवाद, ऐसा लगता है कि आप हाइबरनेट के एक दर्शक हैं, क्योंकि आपके पास मेरे प्रश्न का उत्तर है: stackoverflow.com/questions/5350770/… । और अब मुझे यकीन नहीं है कि रिश्ते पर पकड़ है, क्योंकि मैं टिप्पणी में अधिक नहीं लिख सकता हूं, इसलिए मैं इसे यहां पोस्ट करता हूं dpaste.de/J85m। कृपया कृपया एक जांच करें यदि संभव हो। :)
hguser

@hguser: आप अंत में आप रिश्ते द्विदिश बनाने के लिए निर्णय लेते हैं, मुझे लगता है कि यह कॉल करने के लिए बेहतर होगा setGroup()से addUser()आदेश दोनों पक्षों लगातार धारण करने के लिए में।
axtavt

अगर मैं ग्रुपग्रुप () को group.addUser () के बारे में नहीं कहूं तो कैसा रहेगा?
hguser

@ ह्ग्युसर: रिश्ते को जारी नहीं रखा जाएगा, जवाब में बिंदु 2 देखें। आप setGroup()बिना कॉल कर सकते हैं addUser(), लेकिन इसके परिणामस्वरूप स्मृति में वस्तुओं की असंगत स्थिति होगी।
दोपहर

मैंने पाया कि मैं एक सही मैपिंग नहीं कर सकता, क्या आप कुछ समय के लिए गीथब में मेरे प्रोजेक्ट की जांच कर सकते हैं? यह एक छोटी परियोजना है।
hguser

31

दो मुख्य अंतर हैं।

संघ पक्षों तक पहुँचना

पहला संबंध इस बात से है कि आप रिश्ते को किस तरह से एक्सेस करेंगे। एक यूनिडायरेक्शनल एसोसिएशन के लिए, आप केवल एक छोर से एसोसिएशन को नेविगेट कर सकते हैं।

इसलिए, एक यूनिडायरेक्शनल @ManyToOneएसोसिएशन के लिए, इसका मतलब है कि आप केवल उस बच्चे की तरफ से रिश्ते का उपयोग कर सकते हैं जहां विदेशी कुंजी रहती है।

यदि आपके पास एक यूनिडायरेक्शनल @OneToManyएसोसिएशन है, तो इसका मतलब है कि आप केवल उस मूल पक्ष से संबंध तक पहुंच सकते हैं जहां विदेशी कुंजी रहती है।

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

आपको यह सुनिश्चित करने के लिए कि दोनों पक्षों को ठीक से सिंक्रनाइज़ किया गया है, द्विदिश संघों के लिए उपयोग / हटाने के तरीकों का उपयोग करने की आवश्यकता है ।

प्रदर्शन

दूसरा पहलू प्रदर्शन से संबंधित है।

  1. इसके लिए @OneToMany, यूनिडायरेक्शनल संघों के साथ ही साथ द्विदिश नहीं हैं
  2. यदि हाइबरनेट यह नहीं बता सकता है कि क्या प्रॉक्सी को सौंपा जाना चाहिए या एक अशक्त मूल्य होना चाहिए@OneToOne , तो इसके लिए , एक अप्रत्यक्ष संघ माता-पिता को उत्सुकता से ले जाएगा
  3. के लिए @ManyToMany, संग्रह प्रकार काफी अंतर के रूप में बनाता है Setsतुलना में बेहतर प्रदर्शनLists

11

कोडिंग के संदर्भ में, एक द्विदिश संबंध को लागू करने के लिए अधिक जटिल है क्योंकि आवेदन जेपीए विनिर्देश 5 (पृष्ठ 42 पर) के अनुसार दोनों पक्षों को एक साथ रखने के लिए जिम्मेदार है। दुर्भाग्य से विनिर्देश में दिए गए उदाहरण अधिक विवरण नहीं देते हैं, इसलिए यह जटिलता के स्तर का एक विचार नहीं देता है।

जब दूसरे स्तर के कैश का उपयोग नहीं किया जाता है, तो यह आमतौर पर रिश्ते के तरीकों को सही तरीके से लागू नहीं करने के लिए एक समस्या नहीं होती है क्योंकि लेनदेन के अंत में उदाहरणों को छोड़ दिया जाता है।

दूसरे स्तर के कैश का उपयोग करते समय, यदि गलत तरीके से लागू किए गए संबंध हैंडलिंग विधियों के कारण कुछ भी दूषित हो जाता है, तो इसका मतलब है कि अन्य लेनदेन भी भ्रष्ट तत्वों को देखेंगे (दूसरा स्तर कैश वैश्विक है)।

एक सही ढंग से कार्यान्वित द्वि-दिशात्मक संबंध प्रश्न और कोड को सरल बना सकता है, लेकिन इसका उपयोग नहीं किया जाना चाहिए यदि यह वास्तव में व्यावसायिक तर्क के संदर्भ में समझ में नहीं आता है।


9

मुझे 100% यकीन नहीं है कि यह एकमात्र अंतर है, लेकिन यह मुख्य अंतर है। हाइबरनेट डॉक्स द्वारा द्वि-दिशात्मक संघों को रखने की भी सिफारिश की जाती है:

http://docs.jboss.org/hibernate/core/3.3/reference/en/html/best-practices.html

विशेष रूप से:

द्विदिश संघों को प्राथमिकता दें: अप्रत्यक्ष संघों को क्वेरी करना अधिक कठिन है। एक बड़े आवेदन में, प्रश्नों में दोनों दिशाओं में लगभग सभी संघों को नेविगेट करने योग्य होना चाहिए।

मुझे व्यक्तिगत रूप से इस कंबल की सिफारिश के साथ थोड़ी सी समस्या है - ऐसा लगता है कि ऐसे मामले हैं जहां एक बच्चे के पास अपने माता-पिता के बारे में जानने का कोई व्यावहारिक कारण नहीं है (उदाहरण के लिए, ऑर्डर आइटम को ऑर्डर के बारे में जानने की आवश्यकता क्यों है? के साथ जुड़े;), लेकिन मुझे इसमें समय का उचित हिस्सा भी मूल्य दिखता है। और चूंकि द्वि-दिशात्मकता वास्तव में कुछ भी चोट नहीं पहुंचाती है, इसलिए मुझे इसका पालन करने के लिए बहुत आपत्तिजनक नहीं लगता है।


द्वि-दिशात्मकता कुछ मामलों में चोट कर सकती है, जैसा कि axtavt ने समझाया है! मैं एक हाइबरनेट इकाई में मैप किए गए हर संबंध के साथ बहुत सावधान रहूंगा! आप हाइबरनेट में चीजों को लोड करने के लिए आवश्यक अंतहीन समय के साथ समाप्त कर सकते हैं, जब तक कि आप वास्तव में नहीं जानते कि आप क्या कर रहे हैं। उपयोग मामलों के बारे में सावधानी से सोचें और विभिन्न उपयोग मामलों के लिए विभिन्न मॉडल कक्षाओं का उपयोग करें। F.ex. चीजों की एक सूची में, मुझे सभी संबंधित वस्तुओं की आवश्यकता नहीं है, बस एक लेबल और आईडी। इसलिए सूची इकाई मेरे लिए, विस्तार इकाई की तुलना में एक अलग (और बहुत सरल) है।
श्लोट्टी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.