2009-03-04 14 views
83

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

धन्यवाद !!

उत्तर

111

Hibernate forum से:

इस किताब से कार्रवाई में हाइबरनेट। अच्छा एक यह पढ़ ..


पहचानकर्ता द्वारा वस्तुओं प्राप्त कर रहा है निम्नलिखित हाइबरनेट कोड स्निपेट डेटाबेस से एक उपयोगकर्ता वस्तु को पुन: प्राप्त:

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

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

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

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

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

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

+1

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

+7

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

+15

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

14

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

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

+0

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

+0

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

9

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

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

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

0

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

1

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

यहां इस परिदृश्य को एक ही पहचानकर्ता के साथ ऑब्जेक्ट के साथ काम करने वाले दो सत्रों के साथ स्केच करने का प्रयास किया गया है। डीबी में वस्तु के लिए प्रारंभिक संस्करण 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 के एक आशावादी लॉक अपवाद के साथ असफल करने के लिए प्रतिबद्ध चाहते है, लेकिन यह यहाँ सफल होगा।

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

2

एक और अतिरिक्त बिंदु :: हाइबरनेट सत्र वर्ग के

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

0

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

0

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

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

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