views:

97

answers:

3

By default, NHibernate lazy loads all collections, which works fine for me in most cases. However, I'm running into problems with some tools that use reflection, which doesn't play well with proxied objects. In this case, I can't serialize an entity using JSON.NET because it throws an exception when it hits a proxied object.

My question is, is there any way to tell a session to disable lazy loading on ALL entities for the lifetime of that session? I know you can do it for a particular type but I want to be able to do it for all entities.

A: 

I believe that this is not possible as classes and properties become lazy (through configuration - XML or Fluent) when the ISessionFactory is build and that happens only once at the beginning of the application's lifetime. It is there, that the actual proxy classes are generated and used to take care of lazy loading.

I do not know if it is helpful for you but you can get the underlying proxy's type (the actual entity type) like this:

Type t = entity.GetType().BaseType;

"entity" being your antity that comes as a proxy.

Furthermore you can instead use DTO's to serialize with JSON.NET instead of the actual entities using an object-object mapper like AutoMapper to assist you on that.

tolism7
How do you convert an entity to a DTO?
Daniel T.
It is not actually converting... it is more of generating a Data Transfer Object (DTO) out of an entity. The idea is to create an object to hold all the data that your entity holds in order to be able to transfer this object through a web service or serialize it etc. Usually this happens manually BUT a better way is to allow a library to do that for you automatically. See this: http://automapper.codeplex.com/
tolism7
+2  A: 

You can use sessionFactory.OpenStatelessSession(), and you'll get an IStatelessSession instance, which doesn't use lazy loading.

Be aware that IStatelessSession has a simplified model that doesn't track changes. It seems adequate for your use case, though.

Diego Mijelshon
This sounds like it should work fine. I'm only grabbing data for viewing, and when you serialize it, the persistence info is lost anyway.
Daniel T.
I ended up using NHibernateUtil.Initialize(entity). This gives me the flexibility of having lazy loading by default but I can selectively eager load an entity if I need to.
Daniel T.
A: 

If you don't want to use the stateless session for whatever reason, you can eager fetch in your query.

Criteria:
.SetFetchMode("ClassName", FetchMode.Eager)

HQL:

string hql = "from Order o" +
             " inner join fetch o.OrderLines" +
             " inner join fetch o.Customer" +
             " where o.Id=:id";
Daniel Auger