NHibernate unintential 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 9:54 UTC
Read the original article Hit count: 268

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_
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
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
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

Related posts about c#

Related posts about Performance