Feel like a geek and get yourself Ema Personal Wiki for Android and Windows

17 September 2009

Fetchmode.Eager, but still a proxy

I just had an issue where i could not cast a property of type Proxy_blah_blah_blah to the type that it really should have been ("Patient", in this case). The issue was still there after i explicitly set the fetchmode to "Eager": NHibernate seemed to ignore the fetchmode.

In a way, it actually did ignore the fetchmode. I am not sure if this is by design. I did not look this up, but blog the cause for future reference.

The problem was that the objects which were to be loaded eagerly, were already fetched by a previous query which had fetchmode lazy for these objects. So the objects were already present in the current session as proxies. Apparently NHibernate does not re-evaluate the lazyness of the objects if another query wants these objects to be fetched eagerly. I can understand this, because it is impossible to change existing objects to another type + nhibernate obviously wants to return the same objects from the same session.

To summerize the problem:

1. a query loads objects which have a reference to Patient which has a lazy initialized property Person
2. The property Person is now a proxy, in my case the proxy of a base class of Person
3. a second query loads objects that also have a reference to Patient. The query has fetchmodes for associationpath 'Patient' = Fetchmode.Eager and for associationpath 'Patient.Person' = Fetchmode.Eager.
4. Nhibernate now in a way ignores the fetchmode properties: in nhprof the query looks good, but the returned object tree has the previously created proxy objects instead of the resolved objects.
5. Using the Person property as a Person object now fails, because it is a proxy of a base class of Person.

A solution would be to use multiple sessions. The solution i chose in this setup is to eagerly load the objects in the first query, which made sense anyway.

1 comment:

Ayende Rahien said...

The issue that you run into is NHibernate identity map.
NH can't give you a different instance than the one you already got