वास्तविकता अधिक जटिल है। जब आप session.Load
का उपयोग करके इकाई लोड करते हैं या आप ऐसी संपत्ति तक पहुंचते हैं जो आलसी लोडेड NHibernate प्रॉक्सी ऑब्जेक्ट देता है। उस प्रॉक्सी ऑब्जेक्ट हाइड्रेटेड द्वारा किया जाएगा (डेटा डीबी से लोड किया जाएगा) जब आप पहली बार अपनी किसी भी संपत्ति का उपयोग करते हैं। यह एनएचबीर्नेट प्राप्त करने के लिए प्रॉक्सी क्लास उत्पन्न करता है जो इकाई वर्ग बढ़ाता है और सभी संपत्ति गेटर्स और सेटर्स को ओवरराइड करता है। यह पूरी तरह से काम करता है जब विरासत का उपयोग नहीं किया जाता है क्योंकि आपके पास प्रॉक्सी और इकाई वर्ग (प्रॉक्सी बेस क्लास) के बीच अंतर करने का कोई तरीका नहीं होगा, उदा। सरल परीक्षण proxy is MyEntity
हमेशा काम करेगा।
अब कल्पना है कि हम एक व्यक्ति इकाई है:
class Person {
// lazy-loaded
public Animal Pet { get; set; }
}
और हम भी Animal
वर्ग पदानुक्रम है:,
public abstract class Animal { ... }
public class Cat { ... }
public class Dog { ... }
अब मान लेते हैं कि Pet
संपत्ति आलसी लोड होता है जब आप व्यक्ति के लिए NHibernate पूछना पालतू जानवर आपको प्रॉक्सी ऑब्जेक्ट मिलेगा:
var pet = somePerson.Pet; // pet will be a proxy
लेकिन Pet
आलसी लोड की गई संपत्ति है, एनएच यह नहीं जान पाएगा कि यह Cat
या Dog
का उदाहरण होगा, इसलिए यह सबसे अच्छा होगा और एक प्रॉक्सी बनाएगा जो Animal
बढ़ाता है। प्रॉक्सी pet is Animal
के लिए परीक्षण पास करेगी लेकिन pet is Cat
या pet is Dog
के लिए परीक्षण विफल हो जाएगी।
अब मान लें कि आप pet
ऑब्जेक्ट की कुछ संपत्ति तक पहुंचेंगे, जिससे एनएच डीबी से डेटा लोड कर सके। अब एनएच को पता चलेगा कि आपके पालतू जानवर उदा। एक Cat
लेकिन प्रॉक्सी पहले से ही जेनरेट की गई है और इसे बदला नहीं जा सकता है। यह एनएचबीर्नेट को चेतावनी जारी करने के लिए मजबूर करेगा कि pet
के लिए मूल प्रॉक्सी Animal
टाइप Cat
टाइप करने के लिए संकुचित हो जाएगी। इसका मतलब है कि पर pet.Id
के साथ जानवर के लिए प्रॉक्सी ऑब्जेक्ट से session.Load<Animal>(pet.Id)
का उपयोग करके आप Cat
का विस्तार करेंगे। इसका मतलब यह भी है कि Cat
अब सत्र के एक हिस्से के रूप में संग्रहीत है, अगर हम पहले व्यक्ति के साथ बिल्ली साझा करने वाले दूसरे व्यक्ति को लोड करते हैं, तो एनएच आलसी लोड की गई संपत्ति को पॉप्युलेट करने के लिए पहले ही उपलब्ध Cat
प्रॉक्सी उदाहरण का उपयोग करेगा।
परिणामों में से एक यह होगा कि pet
पर ऑब्जेक्ट संदर्भ session.Load<Animal>(pet.Id)
(object.ReferencesEqual
समझ में) द्वारा प्राप्त संदर्भ अलग होगा।
अब
जब यह आपके लिए नुकसान का कारण हो सकता है:
जब आप Set
रों करने या अपने कोड में Dictionary
एँ या में अपने संस्थाओं डाल आप किसी भी अन्य संरचना कि Equals/GetHashCode
जोड़ी काम करने की आवश्यकता है का उपयोग करता है, तो । इसे कस्टम Equals/GetHashCode
कार्यान्वयन प्रदान करके आसानी से तय किया जा सकता है (देखें: http://www.onjava.com/pub/a/onjava/2006/09/13/dont-let-hibernate-steal-your-identity.html?page=1)
जब आप अपनी प्रॉक्सी ऑब्जेक्ट को लक्ष्य प्रकार पर डालने का प्रयास करते हैं उदा। (Cat)pet
, लेकिन फिर वहाँ समाधान पता कर रहे हैं (जैसे Getting proxies of the correct type in NHibernate)
तो नैतिक आपके डोमेन मॉडल में संभव विरासत के रूप में के रूप में ज्यादा से बचना है।
क्या यह एक बड़ा सौदा है? अगर हम इस चेतावनी को अनदेखा करते हैं तो क्या होता है? – Beatles1692
यह एक बड़ा सौदा है या नहीं, उस जोखिम के स्तर पर निर्भर करता है जिसे आप स्वीकार करना चाहते हैं। चूंकि आपके कोड और आपके डेटाबेस के बीच हमेशा डिस्कनेक्ट होने जा रहा है, इसलिए आप हमेशा यह सुनिश्चित नहीं कर सकते कि कास्टिंग काम करेगा। यह उन बगों का कारण बन जाएगा जो निदान करना मुश्किल हो सकता है और डेटाबेस या कोड में बदलाव किए बिना हल नहीं किया जा सकता है। – Fourth