简体   繁体   中英

NHibernate not lazy loading

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?

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 .

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM