2

I'm using NHibernate 3.3.3.4001. I'm having an issue where NHibernate is not lazy loading data when issuing a Get request. Instead it is populating the entire object model resulting in very slow performance. The .hbm file is as follows:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 
                   assembly="My.Assembly" namespace="Assembly.Model">

  <class name="Parent" table="tblParent">
    <id name="ID">
        <generator class="native"></generator>
    </id>
    <version name="Version" column="Version"/>    
    <component name="Children">
      <bag name="Collection" table="tblChildren" 
                             cascade="save-update, merge" inverse="true">
        <key column="ParentID"></key>
        <one-to-many class="Children"></one-to-many>
      </bag>
    </component>
    <property name="DateCreated" column="DateCreated" update="false" insert="false" />
    <property name="Inactive" column="Inactive" />
  </class>

</hibernate-mapping>

I had expected NHibernate to load all child objects lazily and not send queries to the database. I have tried adding explicit lazy = true and default-lazy=true but it made no difference. I have inspected the Config object and can see that the mappings have islazy=true.

I am calling Get as follows:

using (var transaction = Session.BeginTransaction())
{
    t = Session.Get<T>(id);
    transaction.Commit();
}

I am puzzled as to why this is not loading lazily but is querying the database for all the child objects?

2 Answers 2

2

Not sure if I do understand your real goal. Is the content of the component in the snippet above complete? or is it just a shorten version?

Anyway, as stated here: 5.1.13. component, dynamic-component (cite)

The <component> element maps properties of a child object to columns of the table of a parent class....

So, the idea behind is mostly to use it like a reference object from C# perspective, while beeing stored in one table. The example 7.1. Dependent objects

<class name="Eg.Person, Eg" table="person">
    <id name="Key" column="pid" type="string">
        <generator class="uuid.hex"/>
    </id>
    <property name="Birthday" type="date"/>
    <component name="Name" class="Eg.Name, Eg">
        <parent name="NamedPerson"/> <!-- reference back to the Person -->
        <property name="Initial"/>
        <property name="First"/>
        <property name="Last"/>
    </component>
</class>

Because the entities look like this:

public class Person
{
    ...
    public virtual Name Name { get; set; }

public class Name
{
    public virtual Person NamedPerson { get; set; }
    public virtual string Initial { get; set; }    
    ...

So, if in your case, Children <component> is in fact just a collection - do not use the above mapping but something like this:

Parent:

<class name="Parent" table="tblParent">
  <id name="ID" generator="native" />
  <version name="Version" column="Version"/>    

  <!-- just a bag -->
  <bag name="Children" table="tblChildren" cascade="save-update, merge" inverse="true">
    <key column="ParentID"></key>
    <one-to-many class="Child"></one-to-many>
  </bag>

  <property ...
</class>

Child:

<class name="Child" table="tblChildren">
  ...
  <many-to-one name="Parent" column="ParentID" />
  ...

And C#:

public class Parent
{
    public virtual IList<Child> Children { get; set; }
    ...

public class Child
{
    public virtual Parent Parent { get; set; }
    ...

And all the loading for sure will be lazy.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, this put me on the right track. The main issue was having the <bag> nested inside a <component>
Right, great to see that. Enjoy NHibernate, great tool ;)
0

You are trying to load collection of components. I don't think it is possible to load them lazily. Try converting your component to a first class entitiy.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.