-->
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.  [ 8 posts ] 
Author Message
 Post subject: Recursive operations and proxies and this
PostPosted: Tue Jan 08, 2008 2:01 am 
Newbie

Joined: Mon Jul 09, 2007 2:28 am
Posts: 3
Hi

I have just debugged a bit of a problem caused by proxies that I found quite a gotcha. I'm modelling an organisation structure in my application and I have a method on my OrganisationUnit class for searching up the tree for a unit satisfying a min unit type level. The method is recursive:

Code:
public virtual OrganisationUnit GetSatisfying(UnitType level)
{
    if (Satisfies(level))
    {
        return this;
    }
    else
    {
        if (parent != null)
            return parent.GetSatisfying(level);
        else
            return this;
    }
}


The problem is when nHibernate proxies are involved and I return "this" in the preceding method I'm returning the member object of the proxy, the real object, instead of the proxy if one exists. I read the advice on testing for the type when dealing with proxies but I don't remember anything on this one.

This results in problems in other searches and comparisons because I end up comparing this real object to the proxy version in other code and of course they are not the same object instance.

I suppose I could use Equals in other comparisons and in this circumstance I could probably move the test one level up and check the parent and return that if successful but still it is a little un-nerving.

I'm not sure if this is completely possible but could the nHibernate DynamicProxy interceptor replace any references to the real object with references to the proxy object on return from method calls?

Cheers
Duncan


Top
 Profile  
 
 Post subject: Recursive operations and proxies and this
PostPosted: Tue Jan 08, 2008 12:14 pm 
Senior
Senior

Joined: Thu Jun 21, 2007 8:03 am
Posts: 127
Location: UK
Hi Duncan,

I have seen the same problem (although it took me a lot longer than you to discover what I'd done).

I discussed it here: http://forum.hibernate.org/viewtopic.php?t=981912

I don't think the access to the 'this' pointer goes through an overrideable method, so Dynamic Proxy wouldn't be able to change the return value.

Regards,
Richard


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 10, 2008 7:41 pm 
Newbie

Joined: Mon Jul 09, 2007 2:28 am
Posts: 3
Hi Richard

Thanks for the reply and the link. In regards to the 'this' pointer i'm talking about the DynamicProxy interceptor replacing it during the method call it is a return or output parameter of. I remember from some small work I did with DynamicProxy that the interceptor recieves an array of objects and returns an object for all methods it is proxying. I expect the 'this' pointer is just another object reference either in either the array of objects if an output parameter or the return object if the return value of the method. I would also expect the interceptor would have access to the real object it is proxying for obvious reasons and could compare any object references to it... Not sure if the interceptor has a reference to the dynamically generated proxy though??

Cheers
Duncan


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 10, 2008 11:55 pm 
Beginner
Beginner

Joined: Tue Sep 04, 2007 12:36 pm
Posts: 23
Hi!
Here is a code snippet that accepts an object, if the object is a proxy, it converts it to the normal implementation without changing the session

Code:
public static object Unproxy(object vo)
        {
            if (vo is INHibernateProxy)
            {
                LazyInitializer li = NHibernateProxyHelper.GetLazyInitializer((INHibernateProxy)vo);
                return li.GetImplementation();
            }

            return vo;
        }

Perhaps you could un-proxy "this" before you return it was my thought...

Would this be of any use to you?

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


Top
 Profile  
 
 Post subject: Recursive operations and proxies and this
PostPosted: Fri Jan 11, 2008 6:03 am 
Senior
Senior

Joined: Thu Jun 21, 2007 8:03 am
Posts: 127
Location: UK
Hi,

Duncan, the interceptor does indeed have access to both the proxy and the 'real' object. I think your suggestion would be possible.

Pete, that's a neat little peice of code. If it's ok with you, I might add that to my blog as a way of handling comparison with 'this'.

However, the problem Duncan has is not to un-proxy the object, but to re-proxy it.

Something like this should work:

Code:

private OrganisationUnit This
{
    get
    {
        return Session.Load<OrganisationUnit>(typeof(OrganisationUnit), Id);
    }
}

public virtual OrganisationUnit GetSatisfying(UnitType level)
{
    if (Satisfies(level))
    {
        return This; // property accessor
    }
    else
    {
        if (parent != null)
            return parent.GetSatisfying(level);
        else
            return This; // property accessor
    }
}



Regards,
Richard


Top
 Profile  
 
 Post subject: Recursive operations and proxies and this
PostPosted: Fri Jan 11, 2008 6:39 am 
Senior
Senior

Joined: Thu Jun 21, 2007 8:03 am
Posts: 127
Location: UK
Duncan,

One other thing ... Ayende has blogged previously on a feature that will be in a future NHibernate release:
http://www.ayende.com/Blog/archive/2007/04/17/Advance-Extending-NHibernate-Proxies.aspx

This would allow you to switch in your own interceptor that could do what you wanted.

Cheers,
Richard


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jan 13, 2008 4:40 am 
Newbie

Joined: Mon Jul 09, 2007 2:28 am
Posts: 3
Hi,

Thanks for the additional suggestions. At the moment though I think I will just use equals for comparisons which will test equality correctly with my setup. I figure that the problem will only stretch as far as equality and will not be as bad as having two distinct instances of the real object which would have some more insidious consequences on the operation of my model.

Thanks again,
Duncan


Top
 Profile  
 
 Post subject: Re: Recursive operations and proxies and this
PostPosted: Sun Jan 13, 2008 10:21 am 
Beginner
Beginner

Joined: Tue Sep 04, 2007 12:36 pm
Posts: 23
FlukeFan wrote:

Pete, that's a neat little peice of code. If it's ok with you, I might add that to my blog as a way of handling comparison with 'this'.



Flukefan, feel free to use it for anything you please!

_________________
^^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.  [ 8 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.