These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 
Author Message
 Post subject: Casting a "Proxy" object as a "Real" obj
PostPosted: Thu Nov 29, 2007 11:12 am 
Beginner
Beginner

Joined: Tue Sep 04, 2007 12:36 pm
Posts: 23
(NHibernate v1.2)

Hi and thanks in advance for the help this problem is really puzzling me.

in the NHibernate docs, there is a note about implementing Implementing Equals() and GetHashCode()... it is written here:

http://www.hibernate.org/hib_docs/nhibernate/1.2/reference/en/html/persistent-classes.html#persistent-classes-equalshashcode

This is code from the example:

Code:
public override bool Equals(object other)
    {
        if (this == other) return true;
       
        Cat cat = other as Cat;
        if (cat == null) return false; // null or not a cat

        if (Name != cat.Name) return false;
        if (!Birthday.Equals(cat.Birthday)) return false;

        return true;
    }


Now imagine that the class Cat is a "lazy" class (in this version of NHibernate every class is lazy by default.)

Then, all of Cat's methods and properties are virtual, and dynamic prxies of Cat are created at runtime.

Do you know what happens if we pass a proxy object into the equality method above?

Code:
Cat cat = other as Cat;
        if (cat == null) return false; // null or not a cat


If the object "other" is a dynamic proxy of cat, this will always return false on the equality, because "cat" is null, because I cannot cast between the proxied object and the real object.

This has some very annoying implications... how can I write this code better?

Is there any method inside the NHibernate library that will return a Cat object from a dynamic proxied object? Do I need to extract an interface out of the "Cat" class? Do I need to get rid of my lazy classes?

any suggestions?

_________________
^^If this post helped you, make sure to rate it Thanks!


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 29, 2007 2:57 pm 
Expert
Expert

Joined: Fri May 13, 2005 11:13 am
Posts: 292
Location: Rochester, NY
Are you sure? My understanding was that the proxy object classes built by NH (via Castle) directly inherit the "real" object class. So, a Cat-proxy "is-a" Cat. Even if "other" is a Cat-proxy,
Code:
Cat cat = other as Cat

will function as expected.

I think this is why this implementation is suggested rather than the MS-recommended Equals() implementation, which explicitly compares GetType() of each object. From the MS docs:

Code:
   public override bool Equals(Object obj)
   {
      // Check for null values and compare run-time types.
      if (obj == null || GetType() != obj.GetType())
         return false;
      Point p = (Point)obj;
      return (x == p.x) && (y == p.y);
   }


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 30, 2007 12:57 pm 
Beginner
Beginner

Joined: Tue Sep 04, 2007 12:36 pm
Posts: 23
marcal wrote:
Are you sure? My understanding was that the proxy object classes built by NH (via Castle) directly inherit the "real" object class. So, a Cat-proxy "is-a" Cat. Even if "other" is a Cat-proxy,
Code:
Cat cat = other as Cat

will function as expected.

I think this is why this implementation is suggested rather than the MS-recommended Equals() implementation, which explicitly compares GetType() of each object. From the MS docs:

Code:
   public override bool Equals(Object obj)
   {
      // Check for null values and compare run-time types.
      if (obj == null || GetType() != obj.GetType())
         return false;
      Point p = (Point)obj;
      return (x == p.x) && (y == p.y);
   }


I used to think that the "Proxied" class inherited from the "Real" class too, but my experiences above have me wondering if this is true.
At any rate, I DID find a solution for this... I'm not sure if I like it, but it DOES work.

Code:
public override bool Equals(object other)
    {
        if (this == other) return true;
       
        Cat cat = UnProxy(other) as Cat;
        if (cat == null) return false; // null or not a cat

        if (Name != cat.Name) return false;
        if (!Birthday.Equals(cat.Birthday)) return false;

        return true;
    }
private static object UnProxy(object item)
  {
   if (item is INHibernateProxy)
   {
    LazyInitializer li = NHibernateProxyHelper.GetLazyInitializer((INHibernateProxy)item);
    return (PublicationInstance)li.GetImplementation();
   }
   return item;
  }


This is a snippet of code from ayende's blog.
Perhaps there is a more elegant approach... any opinions?

_________________
^^If this post helped you, make sure to rate it Thanks!


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.