2011-11-08 14 views
9

मैं समझने की कोशिश कर रहा हूं कि हाइबरनेट 3.6 session.get() और session.load() के ऑब्जेक्ट और व्यवहार में अंतर क्या है।हाइबरनेट 3.6 - session.get() बनाम session.load()

javadoc से

:

प्राप्त():

वापसी दिए गए पहचानकर्ता, या अगर ऐसी कोई लगातार उदाहरण है अशक्त के साथ दिया इकाई वर्ग के लगातार उदाहरण। (उदाहरण के पहले से ही सत्र से संबद्ध है , एक गैर-आरंभिकृत उदाहरण लौटने कि उदाहरण इस विधि कभी नहीं देता है।।)

लोड():

वापसी की लगातार उदाहरण दिए गए इकाई वर्ग को दिए गए पहचानकर्ता के साथ दिया गया है, यह मानते हुए कि उदाहरण मौजूद है। यह विधि एक प्रॉक्सीकृत उदाहरण लौटा सकती है जो ऑन-डिमांड शुरू होती है, जब गैर-पहचानकर्ता विधि का उपयोग किया जाता है।

मैं तीन प्रश्न हैं:

  1. जावाडोक कहना नहीं है जब load() एक प्रॉक्सी वापस कर सकती है - वहाँ किसी भी तरह से अग्रिम में यह पता करने के लिए है?

  2. जब load() प्रॉक्सी देता है - इसका मतलब है load() डेटाबेस तक नहीं पहुंच पाया, क्या मैं सही हूं? तो क्या होगा यदि मैंने load() को पहचानकर्ता के साथ प्रदान किया जो डेटाबेस में मौजूद नहीं है? अब सत्र में एक अमान्य आईडी के साथ प्रॉक्सी होगा (अपवाद प्राप्त किए बिना)। अब मैं एक और लगातार उदाहरण उस प्रॉक्सी को इंगित करना चाहता हूं - क्या यह काम करने जा रहा है? इस परिदृश्य के लिए मुझे प्रॉक्सी को प्रारंभ करने की आवश्यकता नहीं है, मुझे केवल इसकी आईडी चाहिए (जो कि मेरे पास अमान्य है, हालांकि यह डेटाबेस में नहीं है)। तो मुझे लगता है कि मैं पूछ रहा हूं कि मेरा विवरण सही है या नहीं, और मुझे यह सुनिश्चित करने के लिए load()isInitialized() के साथ लौटाई गई वस्तु के बाद जांच करने की आवश्यकता है ताकि यह सुनिश्चित किया जा सके कि यह वैध इकाई (या कम से कम एक वैध प्रॉक्सी) का प्रतिनिधित्व करता है, यानी वैध के साथ आईडी।

  3. इसके अलावा, क्या होता है यदि load() प्रॉक्सी देता है - तो प्रॉक्सी वह उदाहरण है जो पहले ही सत्र से जुड़ा हुआ है। फिर get() के विवरण के अनुसार: "यदि उदाहरण पहले ही सत्र से जुड़ा हुआ है, तो उस उदाहरण को वापस करें।" - get() प्रॉक्सी वापस करता है? चूंकि get() के विवरण के अनुसार: "यह विधि कभी भी एक प्रारंभिक उदाहरण नहीं लौटाती है।"

धन्यवाद!

अद्यतन

सही निम्नलिखित हैं?

(ए) मुझे लगता है कि दोनों load() और get() पहले डीबी पर जाने से पहले सत्र कैश की जाँच करने की कोशिश करेंगे - तो यह कहना है कि उनमें से किसी को हमेशा डीबी मारता है, या हमेशा ही प्रॉक्सी रिटर्न सही नहीं होगा।

(बी) एक प्रारंभ प्रॉक्सी के रूप में आप यहां पढ़ सकते हैं, मूल उदाहरण के रूप में ही नहीं है: http://blog.xebia.com/2008/03/08/advanced-hibernate-proxy-pitfalls/

उत्तर

17

(1), (3):

हां। आप सही हैं। load() और get() पहले जांच करेंगे कि सत्र में उसी पीके के साथ कोई उदाहरण जारी है या नहीं।

यदि हां, तो सत्र से उस उदाहरण को वापस कर दें। (यह प्रॉक्सी या वास्तविक इकाई वर्ग उदाहरण हो सकता है)

यदि नहीं, load() एक प्रॉक्सी बना और वापस करेगा, जबकि get() डीबी हिट करेगा और वास्तविक इकाई वर्ग का उदाहरण देगा।

दोनों तरीकों से लौटाई गई वस्तु को बाद में सत्र में जोड़ा जाएगा और जारी रखा जाएगा।

तो, get() या load() रिटर्न प्रॉक्सी या वास्तविक इकाई वर्ग इस बात पर निर्भर करता है कि आप पहली बार मौजूदा सत्र में उसी पीके का उदाहरण प्राप्त करने के लिए() या लोड() का उपयोग करते हैं या नहीं।

आप प्रमाण निम्न परीक्षण प्रदर्शन करके इस व्यवहार कर सकते हैं:

Session session = HibernateUtil.getSessionFactory().openSession(); 

Item loadItem= (Item) session.load(Item.class, 1); 
System.out.println(loadItem.getClass().getName()); 

Item getItem = (Item) session.get(Item .class, 1); 
System.out.println(getItem .getClass().getName()); 

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

(2):

लोड() एक प्रॉक्सी देता है, तो यह load() दौरान डीबी पर नहीं पहुंच सकेगी व्याप्ति प्रॉक्सी केवल DB तक पहुँचता होगा पी के अलावा उनके मैप किया गुण पहुँचा रहे हैं और वहाँ कोई उदाहरण हैं उसी पीके मान सत्र के साथ जुड़ा हुआ है।

प्रॉक्सी डीबी तक पहुंचने के बाद, प्रॉक्सी के उसी पीके के साथ उदाहरण उस सत्र से जुड़ा होगा। इसलिए जब आपको प्रॉक्सी से फिर से कोई अन्य गुण मिलता है या आप उसी पीके के लिए उदाहरण प्राप्त करने के लिए get() का उपयोग करते हैं, डीबी को एक्सेस नहीं किया जाएगा क्योंकि सत्र से मूल्य मिल सकते हैं।

उदाहरण के लिए:

/**Session starts***/ 
Item item = (Item) session.load(Item.class, new Long(1)); 
item.getId(); //Will not access DB as only the identifier property is access 
item.getDescription(); // access the DB and initialize the proxy . After that , the item proxy is said to be initialized 
item.getPrice(); //will not access DB as the item with the PK 1 can be get from the session 
Item item2 = session.get(Item.class, new Long(1)) //will not access DB as the item with the PK 1 can be get from the session 

आप load() अमान्य आईडी के साथ एक उदाहरण और उसके बाद गुण का उपयोग या इस प्रॉक्सी पर (जैसे isInitialized() के रूप में) एक विधि कॉल करते हैं, ObjectNotFoundException फेंक दिया जाएगा। तो यदि आप ObjectNotFoundException पकड़ सकते हैं, तो इसका मतलब है कि प्रॉक्सी को अमान्य आईडी से लोड किया जाता है।

यदि आप यह सुनिश्चित करना चाहते हैं कि आईडी रनटाइम के दौरान मान्य है, तो आपको get() का उपयोग करना चाहिए और जांचें कि लौटा हुआ उदाहरण शून्य है या नहीं। विदेशी कुंजी बाधा सेट करते समय load() उपयोगी है। this

+0

1 देखें।लेकिन अगर मेरे पास पहले से ही प्रारंभिक उदाहरण (इस आईडी के लिए) सत्र में था, तो क्या वह उस घटना को वापस नहीं करेगा, न कि प्रॉक्सी? इसके अलावा, जावाडोक कहता है: "यह विधि एक प्रॉक्सीकृत उदाहरण लौटा सकती है" - यह नहीं कहती "यह विधि हमेशा होगी"। 2. यह एक प्रकार का डिज़ाइन दोष है - जब आप प्रॉक्सी करते हैं तो आप जो कहते हैं उसके अनुसार और मैं यह सुनिश्चित करना चाहता हूं कि यह डीबी में एक वास्तविक आईडी का प्रतिनिधित्व करता है (और मैं हमेशा यह सुनिश्चित करना चाहता हूं - भले ही मैं केवल उपयोग करता हूं प्रॉक्सी को अन्य उदाहरणों को इंगित करने के लिए) - तब मुझे नहीं पता कि मैं जिस आईडी का उपयोग करता हूं वह वैध है जब तक कि मैं इसे प्रारंभ नहीं करता, लेकिन इस मामले में, प्रॉक्सी का उपयोग क्यों कर रहा है? – rapt

+0

3. क्या आपका मतलब है कि 'लोड() 'लोड()' के बाद प्रारंभिक प्रॉक्सी, या केवल प्रारंभिक उदाहरण लौटाएगा? चूंकि यह बाद में है, तो अब हमारे पास सत्र में दो ऑब्जेक्ट्स हैं जो एक ही आईडी (प्रॉक्सी और इंस्टेंस) रखते हैं। बीटीडब्ल्यू मुझे पता है कि दो प्रॉक्सी होना संभव है जो एक ही डीबी आईडी का प्रतिनिधित्व करता है - जैसा कि आप यहां पढ़ सकते हैं: http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/ टेक्स्ट के तहत " दूसरा, प्रॉक्सी तोड़ना संभव है "। - मेरे मूल प्रश्न में अद्यतन में और देखें। – rapt

+0

हां। आप सही हैं। आपके प्रश्न मुझे 'get() 'और' load() 'के बारे में कुछ गलतफहमी को दूर करने में मदद करते हैं। कृपया मेरे अपडेट देखें –

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