NH force conversion of proxy to concrete class

269 views
Skip to first unread message

Graham Bunce

unread,
Mar 9, 2010, 6:40:39 AM3/9/10
to nhusers
All,

I'm using proxies based on an interface, e.g.

<class name="Thing"
proxy="Domains.Interfaces.IThing, Domains.Interfaces"
table="Thing"
discriminator-value="0">

When I do a Session.Load (or anything that creates a proxy) then the
proxy is based on the interface, IThing. Any code such as this:

Thing obj = (Thing)proxy;

will fail as an "IThing" proxy from NHibernate does not inherit from
"Thing".So far so good, I understand this.

If I then do the following:

Thing obj = null;
if (NHibernateUtil.IsInitialized(proxy))
{
NHibernateUtil.Initialize(proxy)
}
obj = (Thing)proxy;


then the cast will still fail as proxy is STILL a NHibernate proxy and
not the concrete type of "Thing". This is although NH has gone to the
DB, got the data and NHibernateUtil.IsInitialized(proxy) will return
true.

How do I force NH to convert a proxy (from an interface) to a concrete
type? Even a Get will return a proxy as the object still exists in
Session.

Thanks

Fabio Maulo

unread,
Mar 9, 2010, 7:12:16 AM3/9/10
to nhu...@googlegroups.com
unwrap

2010/3/9 Graham Bunce <graha...@hotmail.com>

--
You received this message because you are subscribed to the Google Groups "nhusers" group.
To post to this group, send email to nhu...@googlegroups.com.
To unsubscribe from this group, send email to nhusers+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/nhusers?hl=en.




--
Fabio Maulo

Graham Bunce

unread,
Mar 9, 2010, 8:28:39 AM3/9/10
to nhusers
By unwrap I assume you don't mean an NH function called "unwrap" but I
need to write my own converter to take the proxy to a concrete class -
i.e. create a concrete and copy the properties over?

I'm using NH 2.1.3GA so I guess the new lazy="no-proxy" isn't
available.

There is nothing in NH to do this for me?

Diego Mijelshon

unread,
Mar 9, 2010, 9:39:30 AM3/9/10
to nhusers
(Thing)Session.GetSessionImplementation().PersistenceContext.Unproxy(proxy)

   Diego



--

Graham Bunce

unread,
Mar 9, 2010, 11:20:10 AM3/9/10
to nhusers
Thank you Diego

:)

Graham Bunce

unread,
Mar 9, 2010, 2:07:34 PM3/9/10
to nhusers
To extend this slightly, is there an NHibernate IsProxy method?

I've looked at the NHibernateProxyHelper but nothing in there. The
above almost gave me what I needed but in some edge cases I may have
an initialised proxy that will pass an NHibernateUtil.IsInitialized
check but still not cast to a concrete type.

I've simulated an IsProxy (I think) by comparing a current type to the
NHibernateProxyHelper.GetClassWithoutInitializingProxy method :

entity.GetType() !=
NHibernateProxyHelper.GetClassWithoutInitializingProxy(entity);

but I'm a little concerned that it may fail with some edge cases to
with subclasses etc. Basically, all I need to know know is "Is the
current entity a proxy", regardless of whether its initalised or not.
I can then use the code Diego gave me to sort out what I need to
afterwards.

Thanks

Diego Mijelshon

unread,
Mar 9, 2010, 3:14:29 PM3/9/10
to nhusers
I don't think there is, but if the argument is not a proxy, Unproxy returns it unmodified, so you don't need to check it manually.
You can still use "if (proxy is INHibernateProxy)" if you want.

In any case, if you find yourself doing this often, you should rethink about your design. Most apps shouldn't have to worry about proxies (frameworks might).
In my case, I only needed to do it once to retrieve an instance of the correct type when using inheritance and lazy loading.

   Diego


Graham Bunce

unread,
Mar 9, 2010, 4:06:44 PM3/9/10
to nhusers
Thanks again Diego.

It is a framework but the main issues I'm having is when I have an
interface that (e.g.) restricts properties to getters but the concrete
class has an internal setter to allow controller methods to hook
things together. These controller methods take in an interface but
need to cast to the concrete to access a setter.....

e.g.
AddComponent(IThing item)
{
((Thing).item).Parent = this;
}

I also have a base class that overrides the comparer for equality
checks, but proxies do not inherit from this base class so the
comparer fails to return true for something like
_collection.Contains(item).... as item is a proxy that is not in the
_collection but it's matching concrete type is.

I don't think these are edge case scenarios (and any comments are
welcome)

tbh, I'm coming to the conclusion that nice as proxies from an
interface are, they are more trouble than they are worth.

SedulousTurtle

unread,
Mar 16, 2010, 5:11:34 PM3/16/10
to nhusers
Hi Graham,

I'm a little new to NHibernate but I just stumbled across this wiki
entry that may have your IsProxy method:
(entity is INHibernateProxy)
link:
http://nhforge.org/wikis/howtonh/finding-dirty-properties-in-nhibernate.aspx

Brian

SedulousTurtle

unread,
Mar 16, 2010, 5:48:11 PM3/16/10
to nhusers
Whoops, my last post was redundant with Diego's -- please disregard.

On Mar 16, 5:11 pm, SedulousTurtle <brian.geistwh...@apoc.abbott.com>
wrote:


> Hi Graham,
>
> I'm a little new to NHibernate but I just stumbled across this wiki
> entry that may have your IsProxy method:
> (entity is INHibernateProxy)

> link:http://nhforge.org/wikis/howtonh/finding-dirty-properties-in-nhiberna...


>
> Brian
>
> On Mar 9, 3:07 pm, Graham Bunce <grahambu...@hotmail.com> wrote:
>
>
>
> > To extend this slightly, is there an NHibernate IsProxy method?
>
> > I've looked at the NHibernateProxyHelper but nothing in there. The
> > above almost gave me what I needed but in some edge cases I may have
> > an initialised proxy that will pass an NHibernateUtil.IsInitialized
> > check but still not cast to a concrete type.
>
> > I've simulated an IsProxy (I think) by comparing a current type to the
> > NHibernateProxyHelper.GetClassWithoutInitializingProxy method :
>
> > entity.GetType() !=
> > NHibernateProxyHelper.GetClassWithoutInitializingProxy(entity);
>
> > but I'm a little concerned that it may fail with some edge cases to
> > with subclasses etc. Basically, all I need to know know is "Is the
> > current entity a proxy", regardless of whether its initalised or not.
> > I can then use the code Diego gave me to sort out what I need to
> > afterwards.
>

> > Thanks- Hide quoted text -
>
> - Show quoted text -

Reply all
Reply to author
Forward
0 new messages