Is it possible to enable/disable lazy loading for all entities across a NHibernate Session? - nhibernate

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.

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.

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.

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";

Related

Return Entity Framework objects from WCF

I am working on a WCF service to provide data to multiple mobile clients. Data model is Entity Framework 4.0. Schema is given below.
When i returnt he object of SysUser the result also contains the navigation properties and EntityKey and other EF related stuff. Is it possible that i get the pure object(only the database fields without the relationship etc).
Thanks
Update
the exception occures "Only parameterless constructors and initializers are supported in LINQ to Entities." on followign code:
return (from u in DataSource.SysUsers
where u.UserID == UserID
select new Player(u)
).FirstOrDefault();
You probably want to send DTOs across the wire rather than your EF objects.
You could use something like AutoMapper to populate your DTOs from the EF objects.
I think if you remove the virtual keyword in your SysUser model for the navigation properties, those will not be loaded. Later, if you need to load this properties, you can do it manually as stated here: http://msdn.microsoft.com/en-us/data/jj574232
Now, if you want to make SysUser travel through a WCF service, it is not a good idea. First, your service's client will need a reference to your Models Project... and that doesn't feels right. If you don't reference your Models, you will get a proxy for it, that is more or less the same as Joe R explained about DTOs.
Here is a related answer: https://stackoverflow.com/a/7161377/7720

Entity Framework with POCO Serializable Classes and Lazy Loading

I have set up my POCO classes with ICollection for related objects. They are in a WCF Service, so I have decorated them with DataContract/DataMember. I do not use virtual properties for the related objects, because they create a proxy that won't serialize (I get a seemingly unrelated message, "The underlying connection was closed", but when I remove the virtual modifier, that goes away.)
What I am having trouble understanding is how to lazy-load the collections for related objects. I don't think the POCO's can do that for themselves, because they don't have access to the context.
For example, I have a Company class, which has an ICollection<Principals> property. I usually don't want to load all the Principals when I retrieve a Company, but I would like a reference to Company.Principals to go get them. Clearly, Company simply can't do that on its own.
What are folks doing to combine the desires to have (1) POCO objects, (2) typical WCF Serialization, and (3) lazy-loaded related properties?
Lazy loading requires proxies and virtual navigation properties. If you don't have proxies you must handle loading in different way. For example by using eager loading:
var companies = context.Companies.Include("Principals").ToList();
or with EF 4.1
var companies = context.Companies.Include(c => c.Prinicpals).ToList();
You know which operation should load related principals as well so using eager loading is not a problem. Using lazy loading in WCF service with serialization will always result to load whole object graph.

Running through entities relation tree instead of sending specific DAO queries

as you know, in Seam there are no problems with LazyInitializationException when reading entities's references to subobjects. So is there any problem if I favor running through the tree of relations in order to read the data that I need, instead of sending specific queries to releveant entities' DAOs? Do I break some important guidelinies/priciples?
Consider that the phrase:
"in Seam there are no problems with LazyInitializationException"
It's not true.
In seam there are no problems with LazyInitializationException if you use a pattern where your session is being persisted in the boundary of a long-running conversation.
This means using a Seam injected persistence context like:
#In
private EntityManager entityManager;
Or, if you are using stateful EJBs (bound to conversation scope too):
#PersistenceContext(type = PersistenceContextType.EXTENDED) EntityManager em;
BTW, once you have understand that, there is no problem navigating the relation tree. You should really do it, if you want to bind it to the interface using JSF.
Consider that you may incur in some speed problem if you access to ManyToOne or OneToMany relations in queries that returns more than one result. This is known as n+1 problem, when you basically runs one more roundtrip to the database for each record returned.
Let's summarize:
single detail object -> navigate relation tree
List of other object -> make a single query to the DAO using left join fetch.

NHibernate lazy loading. Retrieve data on demand

I have some class with associated list. I want this list not to be loaded when I retrieve the entity, but I want to have an opportunity to load this list later, outside the session in which I cought the entity.
Can NHibernate's lazy mechanism do this?
Thanks!
In theory you can implement your own IBytecodeProvider / ProxyFactory and do whatever you want. But that's quite complex, so you'll want to stick to regular NHibernate usage, which dictates that lazy loading requires an active session. It can be the originating session or you can reattach an entity from a previous session using ISession.Lock()
From outside of the session, you will always get an exception when you access an not-yet loaded object.
There is a way to get your objects from a new session. What you want to do is known as "Remote Lazy Loading". See http://www.theserverside.com/news/1363571/Remote-Lazy-Loading-in-Hibernate

What is Castle proxy factory in NHibernate?

What is Castle proxy factory in NHibernate? What is its task? What does proxy mean in this case?
Castle can be used (amongst others, you have the choice, you can also use LinFu, Spring.NET, ...) to create dynamic proxies of your entities.
By default, NHibernate uses dynamic proxies to represent your entities; by doing so, it is able to return an object to you when you retrieve some entity from the DB, without all properties being populated. By using a dynamic proxy, it will only populate the entity once you really refer to a property.
(So it is some kind of lazy loading; not to be confused with lazy loading of collections / associations though).
This behaviour is the reason why NHibernate wants you to create every property as virtual by default: NHibernate will create a new class using this Castle (or LinFu, ...) proxy provider which inherits from your entity, and it will override all the properties so that it can 'inject' the code that is necessary to retrieve the necessary data from the DB.
You can disable this behaviour by specifying 'lazy=false' in your entity mapping. (Although, I do think that even if you disable this feature, NHibernate will still require that you use one of the proxy factories).
When you are selecting an entity from ISession you are getting not real entity instance - you are getting proxy object.
This proxy object inherits your entity and used by NHibernate to track changes made to the fields.
see it: http://en.wikipedia.org/wiki/Proxy_pattern