I have a database fetch that handles a full object graph using multiple future queries. It looks something like this (class names have been changed to protect the innocent):
Foo foo;
var fooFuture = Session.QueryOver<Foo>()
.Where(f => f.Id == id)
.Future();
// load up the Blah collection for the Foo
Session.QueryOver<Foo>()
.Fetch(f => f.Blahs).Eager
.Where(f => f.Id == id)
.Future();
// do a separate query for the BlahOptions -- this is needed
// because if we did a Join and Join off of Foo, we'd get duplicate Blah
// results and that's not good
Session.QueryOver<Blah>()
.Fetch(b => b.Options).Eager
.Where(b => b.Foo.Id == id)
.Future();
// load up the Attributes for the Foo
Session.QueryOver<Foo>()
.Fetch(f => f.Attributes).Eager
.Where(f => f.Id == id)
.Future();
foo = fooFuture.SingleOrDefault();
NOTE: I can implement this in NHibernate LINQ, but the behavior remains the same.
The weirdness: foo will sometimes be of type FooNamespace.Foo (the correct, concrete type) and other times it will be Castle.Proxies.FooProxy.
Whether I get the real type or a proxied type seems to depend on whether or not NHibernate has been used previously in the session. When this query occurs after other NHibernate queries, it returns a FooProxy. If it's the first use of the session, it returns a Foo.
Why does this happen? How can I prevent it from happening? I'm purposefully fetching the entire object graph of Foo to make sure there are no proxies. And graph itself doesn't contain any proxies, it's just the root Foo reference. The fact that the returned type depends on what NHibernate has done before seems to be the key (and really weird).
A couple closing notes:
NHibernateUtil.IsInitialized returns true when fed a FooProxy, so I can't assure it's not a proxy that wayFooProxyAny insight is greatly appreciated!
The reason why this would generally happen is because a Foo is loaded elsewhere in the session prior to this point and you are getting the proxy created on that previous query.
I have had some success with the following
var fooProxy = foo as INHibernateProxy;
if(fooProxy != null) {
var context= Session.GetSessionImplementation().PersistenceContext;
foo = context.Unproxy(fooProxy);
}
Though, In most cases the process of serialization seems to convert the Proxy to the correct type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With