lazy-loading and Eagerly loading in Nhibernate - nhibernate

I am using Nhibernate but still i am confused about (lazy-loading and Eagerly loading) these two topics due to poor understanding of Nhibernate.
Please define me lazy-loading and Eagerly loading in simple words.
Also why we use castle.Dynamic Proxy ?

Lazy loading and eager loading are concepts that must be present in every ORM.
Let's take a parent-child relation:
class Parent {
String name;
List<Child> childs;
}
class Child {
String name;
}
When you load an element of Parent, the ORM must decide if it loads the childs collection also (through a join for example) or if it delays the query to load the childs until you actually access the collection
parent.childs.get(0)
When you load the childs collection ahead, ie, before accessing the collection, it is eagerly loading because you are expecting to access the childs. This can be done in a single query, with the disadvantage of bringing more data from the DB.
When you delay the load until the actual collection is accessed, it is called lazy loading, because you are only getting the childs when they are strictly required. This has the benefit of getting only the data when its needed, at the cost of extra queries (for mor on this topic you can query google for "N+1 select hibernate" for example).
If you want to trigger the query for retrieving the childs when the collection is being accessed, you need some sort of callback/interception on the childs collection. This is done through a proxy on the collection, so you can intercept every access to the collection to get data from the db. That's why you need a proxy/interception library such as Castle.

Lazy loading = waiting until code explicitly accesses a property/collection before loading it from the database.
Eager loading = proactively loading that data ahead of time, regardless of whether the code ever uses it or not.
Proxies are used to intercept access to said properties/collections in order to instigate the load.

Related

How to configure not loading node relations even partly?

I am using Spring data Neo4j project while my nodes contains relations properties using #RelatedTo , #RelatedToVia annotations, I don't want any of them to be fetched eagerly so these properties ain't marked with #Fetch annotations.
When node is fetched all his other relations are partly fetched ( each fetched related node only with id the rest of the properties are null) this happens in nested way also for the relations of the relations.
There is way to prevent this overhead? using include/exclude fields like in spring data mongo db?
Thanks
You can have a look here to get a better understanding how the lazy/eager loading in Spring Data Neo4j works:
lazy loading in spring data neo4j
But what you have to remember is that in general what you don't have marked with #Fetch annotation you have to get it yourself with neo4jTemplate.fetch().
This means exactly what you found out by yourself, that if you fetch a property using #RelatedTo annotation, then you have to use fetch for the properties of that property using #RelatedTo annotation.
As far as I know there is no way you can use to avoid this.

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

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

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