NHibernate unintentional lazy property loading
Posted
by chiccodoro
on Stack Overflow
See other posts from Stack Overflow
or by chiccodoro
Published on 2010-06-02T09:33:26Z
Indexed on
2010/06/02
10:03 UTC
Read the original article
Hit count: 274
I introduced a mapping for a business object which has (among others) a property called "Name":
public class Foo : BusinessObjectBase
{
...
public virtual string Name { get; set; }
}
For some reason, when I fetch "Foo" objects, NHibernate seems to apply lazy property loading (for simple properties, not associations):
The following code piece generates n+1 SQL statements, whereof the first only fetches the ids, and the remaining n fetch the Name for each record:
ISession session = ...IQuery query = session.CreateQuery(queryString);
ITransaction tx = session.BeginTransaction();
List<Foo> result = new List<Foo>();
foreach (Foo foo in query.Enumerable())
{
result.Add(foo);
}
tx.Commit();
session.Close();
produces:
NHibernate: select foo0_.FOO_ID as col_0_0_ from V1_FOO foo0_<br/>
NHibernate: SELECT foo0_.FOO_ID as FOO1_2_0_, foo0_.NAME as NAME2_0_ FROM V1_FOO foo0_
WHERE foo0_.FOO_ID=:p0;:p0 = 81<br/>
NHibernate: SELECT foo0_.FOO_ID as FOO1_2_0_, foo0_.NAME as NAME2_0_ FROM V1_FOO foo0_
WHERE foo0_.FOO_ID=:p0;:p0 = 36470<br/>
NHibernate: SELECT foo0_.FOO_ID as FOO1_2_0_, foo0_.NAME as NAME2_0_ FROM V1_FOO foo0_
WHERE foo0_.FOO_ID=:p0;:p0 = 36473
Similarly, the following code leads to a LazyLoadingException after session is closed:
ISession session = ...
ITransaction tx = session.BeginTransaction();
Foo result = session.Load<Foo>(id);
tx.Commit();
session.Close();
Console.WriteLine(result.Name);
Following this post, "lazy properties ... is rarely an important feature to enable ... (and) in Hibernate 3, is disabled by default."
So what am I doing wrong? I managed to work around the LazyLoadingException by doing a NHibernateUtil.Initialize(foo)
but the even worse part are the n+1 sql statements which bring my application to its knees.
This is how the mapping looks like:
<class name="Foo" table="V1_FOO">
...
<property name="Name" column="NAME"/>
</class>
BTW: The abstract "BusinessObjectBase" base class encapsulates the ID property which serves as the internal identifier.
© Stack Overflow or respective owner