2012-12-24 13 views
10

जब जावा में एक UDT के लिए #equals कार्यान्वयन उपलब्ध कराने के शर्तों में से एक है कि पारित कर दिया तर्क वस्तु वर्तमान वर्ग का एक उदाहरण अन्यथा हम असफल फास्ट return falseEffective Java देख होना चाहिए है (EJ2) । हालांकि, हाइबरनेट 4 का उपयोग करते समय हम आलसी लोडिंग के कारण जावासिस्ट प्रॉक्सी उदाहरणों के साथ समाप्त हो सकते हैं जहां यह #equals स्थिति विफल हो जाएगी। इस पर काबू पाने के लिए सबसे अच्छा विकल्प क्या होगा? कुछ विकल्प मैं के बारे में सोच सकते हैं:हाइबरनेट javassist प्रॉक्सी और `वस्तु # equals`

  • खाते में प्रॉक्सी मामले को लेने के equals कार्यान्वयन का विस्तार। विपक्ष: रखरखाव टोल, हाइबरनेट प्रॉक्सी इंफ्रास्ट्रक्चर, हैकी, इकाई या डोमेन मॉडल को हार्डवायर निर्भरता ओआरएम का उपयोग करने के लिए अज्ञेयवादी होना चाहिए, क्योंकि उन्हें विभिन्न संदर्भों में पुन: उपयोग किया जा सकता है जहां ORM की आवश्यकता नहीं है। स्विंग यूआई।
  • जांचें कि यह equals पर आक्रमण करने से पहले प्रॉक्सी है या नहीं। विपक्ष: हमेशा संभव नहीं है, यानी, संग्रह से निपटने और equals के निहित आमंत्रण, उदाहरण के लिए, मानचित्र।
  • आलसी लोडिंग का उपयोग करने से बचें। विपक्ष: सभी उपयोग-मामलों में उचित और न ही कुशल।

अद्यतन

EJ2 की समीक्षा फिर से मुझे विश्वास है कि निम्नलिखित सभी स्थितियों (टाइप-प्रकार, टाइप-प्रॉक्सी, प्रॉक्सी-प्रकार और प्रॉक्सी-प्रॉक्सी) के लिए काम करेंगे, लेकिन जैसा कि टिप्पणियों में से एक में बताया यदि टाइप की तुलना पूरी तरह से अलग प्रकार से की जाती है, तो इसके नीचे लूप हमेशा के लिए हो सकता है Person.equals(Employee) और दोनों समान ईजे 2 मानदंडों का उपयोग करते हैं। वर्ग समानता 1. बदलें instanceof के बजाय बराबरी का उपयोग करें:

if (this.getClass() != anObject.getClass()) 
    { 
     return anObject.equals(this); 
    } 
+0

बस यह सुनिश्चित कर लें कि प्रॉक्सी आपकी इकाई की कक्षा का विस्तार करेगी? –

+0

प्रॉक्सी उदाहरणों का विस्तार नहीं होता है, 'InvocationHandler' और स्थिति' (this.getClass() == anObject.getClass()) देखें, निश्चित रूप से, झूठी का मूल्यांकन करेगा। –

+1

आपने एक विकल्प छोड़ा: प्रभावी जावा सलाह को अनदेखा करें और subclasses को .equals() में अनुमति दें। –

उत्तर

9

मैं एक ही समस्या पर ठोकर खाई। जिस तरह से मैंने तय किया है वह .equals -method को बदलना था।

@Override 
public boolean equals(Object obj) { 
    if (this == obj) 
     return true; 
    if (obj == null) 
     return false; 
    if (!getClass().isAssignableFrom(obj.getClass())) 
     return false; 
    AbstractEntity other = (AbstractEntity) obj; 
    if (getId() == null) { 
     if (other.getId() != null) 
      return false; 
    } else if (!getId().equals(other.getId())) 
     return false; 
    return true; 

चाल वर्गों की तुलना नहीं करने के लिए एक ही हो लेकिन isAssignableFrom -method का उपयोग करें। दूसरी चाल प्रत्यक्ष गुणों का उपयोग नहीं करना है (other.id), लेकिन गेट-विधि का उपयोग करें (other.getId())

+0

getClass()। IsAssignableFrom (obj.getClass()) हमेशा मुझे झूठा देता है –

+0

यह मेरे लिए चाल है। रुचि रखने वालों के लिए: यहां इसका परीक्षण कैसे करें: कर्मचारी कर्मचारी आरएफ = em.getReference (कर्मचारी.क्लास, आईडी); कर्मचारी कर्मचारी = em.find (कर्मचारी.क्लास, आईडी); Asser t.assertTrue (employee.equals (employeeRef)); –

+0

मुझे पहली पंक्ति पर एक स्टैक ओवरव्लो त्रुटि मिल रही है – pozuelog

1

आप दो काम कर सकें। प्रॉक्सी का प्रकार इकाई के प्रकार के बराबर नहीं है, बल्कि इकाई के प्रकार को बढ़ाता है।

  1. खोलना प्रॉक्सी इकाई ही प्राप्त करने के लिए (वहाँ कई हाइबरनेट उपकरण है कि मदद करता है आप ऐसा कर)
+0

प्रॉक्सी का विस्तार नहीं होता है, इसलिए यह काम नहीं करेगा। – Nicktar

6

मुझे विल्म डी विट उत्तर पर टिप्पणी करने की प्रतिष्ठा नहीं है। मुझे एक नया जवाब पोस्ट करने की आवश्यकता है।

के लिए

if (!getClass().isAssignableFrom(obj.getClass())) 

if (!obj.getClass().isAssignableFrom(getClass()) && !getClass().isAssignableFrom(obj.getClass())) 

तो फिर तुम कि बराबरी के सभी स्थितियों (टाइप-प्रकार, प्रकार के लिए काम करेंगे आश्वासन होगा:

djechelon के मुद्दे को हल करने के लिए, आप इस लाइन को प्रतिस्थापित करना चाहिए -प्रॉक्स, प्रॉक्सी-टाइप और प्रॉक्सी-प्रॉक्सी)।

मुझे आपके उत्तर को भी वोट देने की प्रतिष्ठा नहीं है। मैं बहुत दुखी हूँ!

1

DHansen द्वारा जवाब ऊपर करीब है, लेकिन मेरे लिए (हाइबरनेट का प्रयोग करके) इस मुद्दे का हल:

if (!Hibernate.getClass(this).equals(Hibernate.getClass(obj))) { return false; } रूप Dr. Hans-Peter Störr

ने सुझाव दिया इसके अलावा यह हमेशा उपयोग 'ही टिककर खेल' के लिए महत्वपूर्ण है जैसा कि ऊपर विलेम डी विट द्वारा सुझाया गया है।

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