सीतनिद्रा में होना: session.get और session.load के बीच अंतर


88

एपीआई से, मैं देख सकता था कि यह प्रॉक्सी के साथ कुछ करना है। लेकिन मुझे प्रॉक्सी पर बहुत सारी जानकारी नहीं मिली और कॉलिंग session.getऔर के बीच के अंतर को नहीं समझा session.load। क्या कोई कृपया मुझे समझा सकता है या मुझे एक संदर्भ पृष्ठ पर भेज सकता है?

धन्यवाद!!

जवाबों:


117

से हाइबरनेट मंच :

यह हाइबरनेट बुक इन एक्शन से है। अच्छा यह पढ़ें ..


पहचानकर्ता द्वारा ऑब्जेक्ट्स को पुनर्प्राप्त करना निम्न हाइबरनेट कोड स्निपेट डेटाबेस से उपयोगकर्ता ऑब्जेक्ट को पुनर्प्राप्त करता है:

User user = (User) session.get(User.class, userID);

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

User user = (User) session.load(User.class, userID);

लोड () विधि पुरानी है; get () को यूजर रिक्वेस्ट के कारण हाइबरनेट एपीआई में जोड़ा गया। अंतर तुच्छ है:

यदि लोड () कैश या डेटाबेस में ऑब्जेक्ट नहीं मिल रहा है, तो एक अपवाद फेंक दिया गया है। लोड () विधि कभी भी शून्य नहीं होती है। यदि ऑब्जेक्ट नहीं मिल सकता है तो प्राप्त () विधि शून्य हो जाती है।

लोड () विधि एक वास्तविक लगातार उदाहरण के बजाय एक प्रॉक्सी लौटा सकती है। एक प्रॉक्सी एक प्लेसहोल्डर है जो पहली बार एक्सेस होने पर वास्तविक ऑब्जेक्ट के लोडिंग को ट्रिगर करता है; दूसरी ओर, () कभी भी प्रॉक्सी नहीं देता है। Get () और load () के बीच चयन करना आसान है: यदि आप निश्चित हैं कि लगातार वस्तु मौजूद है, और nonexistence को असाधारण माना जाएगा, तो लोड () एक अच्छा विकल्प है। यदि आप निश्चित नहीं हैं कि दिए गए पहचानकर्ता के साथ एक स्थायी उदाहरण है, तो उपयोग करें () और वापसी मान का परीक्षण करें कि क्या यह अशक्त है। लोड का उपयोग करते हुए () का एक और निहितार्थ है: आवेदन एक वैध संदर्भ (एक प्रॉक्सी) को प्राप्त कर सकता है एक सतत उदाहरण के लिए डेटाबेस को मारने के बिना अपनी लगातार स्थिति को पुनः प्राप्त करने के लिए। इसलिए लोड () एक अपवाद नहीं फेंक सकता है जब यह कैश या डेटाबेस में लगातार ऑब्जेक्ट नहीं पाता है; अपवाद को बाद में फेंका जाएगा, जब प्रॉक्सी एक्सेस किया जाता है। बेशक, पहचानकर्ता द्वारा किसी वस्तु को प्राप्त करना, मनमाने प्रश्नों का उपयोग करने जैसा लचीला नहीं है।


1
मैं अभी एक सत्र डिबग कर रहा हूं, जहां सत्र। गेट <टी> () एक प्रॉक्सी लौटा रहा है!
केंट बूगार्ट

7
आपका बहुत बहुत धन्यवाद! मेरे लिए धन का हिस्सा था: "अगर लोड () कैश या डेटाबेस में ऑब्जेक्ट नहीं मिल सकता है, तो एक अपवाद फेंक दिया जाता है। यदि वस्तु नहीं मिल सकती है तो प्राप्त () विधि शून्य हो जाती है।"
क्रिस

15
JavaDoc for Session.get कहता है: दिए गए पहचानकर्ता के साथ दिए गए निकाय वर्ग के लगातार उदाहरण को वापस लौटाएं, या यदि ऐसा कोई लगातार उदाहरण नहीं है, तो शून्य। (यदि उदाहरण के लिए, या उदाहरण के लिए एक प्रॉक्सी, पहले से ही सत्र के साथ जुड़ा हुआ है, तो उस उदाहरण या प्रॉक्सी को वापस लौटाएं।) इसलिए पुस्तक से अनुभाग कहता है: "दूसरी तरफ, () कभी भी एक प्रॉक्सी नहीं लौटाता है।" सही नहीं है।
विक्की

यदि आप अपने डाओस के साथ लेनदेन प्रबंधन रणनीति का उपयोग कर रहे हैं, तो आप प्राप्त करना पसंद कर सकते हैं ()। अन्यथा कॉल करने वाले को भी मामले में लोड () रिटर्न में एक हाइबरनेट सत्र के संदर्भ में निष्पादित करने की आवश्यकता होगी। उदाहरण के लिए, यदि आप MVC कर रहे हैं, तो आपका नियंत्रक dao.load () निष्पादित कर सकता है और तब एक अपवाद फेंक सकता है जब कोई वैध सत्र न होने पर प्रॉक्सी ऑब्जेक्ट को बाद में एक्सेस करने की कोशिश कर रहा है। डेओगेट () सत्र की परवाह किए बिना नियंत्रक को वास्तविक वस्तु लौटाएगा (यह मानते हुए कि यह मौजूद है)
dev

@Vicky द्वारा वर्णित समस्या सिरदर्द पैदा कर सकती है, और मुझे इसका कोई लाभ नहीं दिखता है। कुछ मामलों में मुझे अतिरिक्त पैरामीट्रिक प्रश्नों के लिए पहचानकर्ता की आवश्यकता है। लेकिन जब से ऑब्जेक्ट का एक प्रॉक्सी पहले से ही सत्र में है, तो पहचानकर्ता का रिटर्न शून्य हो जाता है। यदि सत्र में वह प्रॉक्सी है तो वे वास्तविक उदाहरण के बजाय प्रॉक्सी को क्यों प्राप्त करते हैं?
djmj

15

खैर, कम से कम nhibernate में, session.Get (id) डेटाबेस से ऑब्जेक्ट को लोड करेगा, जबकि session.Load (id) केवल आपके सर्वर को छोड़े बिना एक प्रॉक्सी ऑब्जेक्ट बनाता है। अपने POCOs (या POJOs :) में हर दूसरे आलसी-भारित संपत्ति की तरह काम करता है। फिर आप इस प्रॉक्सी का उपयोग ऑब्जेक्ट के संदर्भ के रूप में खुद को संबंध बनाने के लिए कर सकते हैं, आदि।

इसे ऐसे समझें कि कोई ऐसी वस्तु है जो केवल ईद ही रखती है और यदि आपको कभी जरूरत पड़े तो बाकी को लोड कर देगी। यदि आप रिश्तों (जैसे FKs) को बनाने के लिए इसे पास कर रहे हैं, तो आईडी आपको सभी की आवश्यकता होगी।


तो आप कहना चाहते हैं कि लोड (आईडी) पहले डेटाबेस को हिट करने के लिए जाँच करेगा कि यह वैध आईडी है या नहीं और प्रॉक्सी ऑब्जेक्ट को लौटा देगा या नहीं और जब इस ऑब्जेक्ट के गुणों को एक्सेस किया जाता है तो यह डेटाबेस को फिर से हिट करता है? यह एक संभावना नहीं परिदृश्य है? एकल वस्तु लोड करने के लिए दो प्रश्न?
faisalbhagat

नहीं, लोड (आईडी) डीबी के सभी राउंड-ट्रिप्स पर आईडी को मान्य नहीं करेगा। इसका उपयोग केवल तभी करें जब आप सुनिश्चित हों कि आप इसे मान्य हैं।
जॉर्ज अल्वेस

9

सेशन.लोड () डेटाबेस को हिट किए बिना हमेशा "प्रॉक्सी" (हाइबरनेट टर्म) लौटाएगा। हाइबरनेट में, प्रॉक्सी दिए गए पहचानकर्ता मूल्य के साथ एक वस्तु है, इसके गुणों को अभी तक आरंभीकृत नहीं किया गया है, यह सिर्फ एक अस्थायी ऑब्जेक्ट की तरह दिखता है। यदि कोई पंक्ति नहीं मिली, तो यह एक ObjectNotFoundException को फेंकेगा।

session.get () हमेशा डेटाबेस को हिट करता है और वास्तविक वस्तु को वापस करता है, एक ऑब्जेक्ट जो डेटाबेस पंक्ति का प्रतिनिधित्व करता है, प्रॉक्सी नहीं। यदि कोई पंक्ति नहीं मिली, तो यह अशक्त हो जाती है।

इन तरीकों के साथ प्रदर्शन भी अलग बनाता है। दो के बीच में...


3

एक और अतिरिक्त बिंदु ::

यदि हाइबरनेट सत्र वर्ग रिटर्न की विधि शून्य हो जाती है, तो वस्तु कैश में और डेटाबेस पर नहीं मिलती है। यदि लोड () विधि ObjectNotFoundException को फेंकता है यदि ऑब्जेक्ट कैश के साथ-साथ डेटाबेस पर नहीं मिला है, लेकिन कभी भी शून्य नहीं लौटा है।


2

"प्राप्त" के बजाय "लोड" का उपयोग करने का एक अप्रत्यक्ष परिणाम यह है कि संस्करण विशेषता का उपयोग करके आशावादी लॉकिंग काम नहीं कर सकता है जैसा कि आप अपेक्षा करते हैं। यदि लोड केवल एक प्रॉक्सी बनाता है और डेटाबेस से नहीं पढ़ता है, तो संस्करण संपत्ति लोड नहीं होती है। संस्करण केवल तभी लोड किया जाएगा जब / यदि आप बाद में ऑब्जेक्ट पर एक संपत्ति का संदर्भ देते हैं, तो एक चयन को ट्रिगर करना। इस बीच, एक और सत्र ऑब्जेक्ट को अपडेट कर सकता है, और आपके सत्र का मूल संस्करण नहीं होगा कि इसे आशावादी लॉक चेक करने की आवश्यकता है - इसलिए आपके सत्र का अद्यतन बिना किसी चेतावनी के दूसरे सत्र के अपडेट को अधिलेखित कर देगा।

यहां एक ही पहचानकर्ता के साथ एक वस्तु के साथ काम करने वाले दो सत्रों के साथ इस परिदृश्य को समाप्त करने का प्रयास किया गया है। DB में ऑब्जेक्ट के लिए प्रारंभिक संस्करण 10 है।

Session 1                  Session 2
---------                  ---------
Load object
Wait a while..   
                           Load object
                           Modify object property
                           [triggers db 'select' -
                            version read as 10]
                           Commit
                           [triggers db update,
                            version modified to 11]
Modify object property
  [triggers db 'select' -
  version read as 11]
Commit
  [triggers db update,
  version modified to 12]

हम वास्तव में एक आशावादी लॉक अपवाद के साथ सत्र 1 की असफलता चाहते हैं, लेकिन यह यहां सफल होगा।

समस्या के चारों ओर "लोड" के बजाय "गेट" का उपयोग करना, क्योंकि प्राप्त तुरंत एक चयन जारी करेगा, और आशावादी लॉक चेकिंग के लिए सही समय पर संस्करण संख्याओं को लोड किया जाएगा।


0

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


0

Http://www.mkyong.com/hibernate/different-between-session-get-and-session-load
session.load () पर एक उत्कृष्ट विवरण पाया जाता है :
यह हमेशा "प्रॉक्सी" (हाइबरनेट शब्द) के बिना लौटेगा डेटाबेस मार रहा है।
हाइबरनेट में, प्रॉक्सी दिए गए पहचानकर्ता मूल्य के साथ एक वस्तु है, इसके गुणों को अभी तक आरंभीकृत नहीं किया गया है, यह सिर्फ एक अस्थायी ऑब्जेक्ट की तरह दिखता है।
यह हमेशा दिए गए पहचान मूल्य के साथ एक प्रॉक्सी ऑब्जेक्ट लौटाएगा, यहां तक ​​कि पहचान मूल्य डेटाबेस में मौजूद नहीं है। हालाँकि, जब आप डेटाबेस से गुण प्राप्त करके प्रॉक्सी को आरंभ करने का प्रयास करते हैं, तो यह डेटाबेस को चुनिंदा कथन के साथ हिट करेगा। यदि कोई पंक्ति नहीं मिली है, तो एक ObjectNotFoundException फेंक देगा।
session.get ():
यह हमेशा डेटाबेस को हिट करता है (यदि कैश में नहीं पाया जाता है) और वास्तविक वस्तु को लौटाता है, एक ऑब्जेक्ट जो डेटाबेस पंक्ति का प्रतिनिधित्व करता है, प्रॉक्सी नहीं।
यदि कोई पंक्ति नहीं मिली, तो यह अशक्त हो जाती है।


0

लोड () कैश या डेटाबेस से ऑब्जेक्ट नहीं मिल सकता है, एक अपवाद फेंक दिया गया है और लोड () विधि कभी भी शून्य नहीं लौटाती है।

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.