-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 
Author Message
 Post subject: Why does NHibernate Fetch data that has not been asked for?
PostPosted: Sat Jun 09, 2007 8:34 pm 
Newbie

Joined: Sat Jun 09, 2007 8:22 pm
Posts: 9
Hibernate version: 1.2

Mapping documents:
Code:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="eStore.Domain.Entities" assembly="eStore.Domain">
    <class name="CustomerEntity" table="Customer">
        <id name="customerId" column="CustomerId" access="field" type="guid">
            <generator class="guid.comb" />
        </id>
        <property name="FirstName" column="FirstName" type="string" length="50" />
        <property name="LastName" column="LastName" type="string" length="50" />
        <property name="UserName" column="UserName" type="string" length="50" />
        <property name="Password" column="Password" type="string" length="50" />
        <property name="IsGold" column="IsGold" type="boolean" />
        <bag name="orders" access="field" inverse="true" lazy="false">
            <key column="CustomerId" />
            <one-to-many class="OrderEntity" not-found="ignore" />
        </bag>
    </class>
</hibernate-mapping>

Code between sessionFactory.openSession() and session.close():
Code:
            using (ISession session = sessionFactory.OpenSession())
            {
                CustomerEntity customer = session.CreateCriteria(typeof(CustomerEntity))
                    .Add(Expression.Eq("UserName", "jyoung"))
                    .UniqueResult<CustomerEntity>();
            }


Name and version of the database you are using: MS SQL 2005

The generated SQL (show_sql=true):
Code:
SELECT orders0_.CustomerId as CustomerId__1_, orders0_.OrderId as OrderId1_, orders0_.OrderId as OrderId3_0_, orders0_.DateCreated as DateCrea2_3_0_, orders0_.Status as Status3_0_, orders0_.CustomerId as CustomerId3_0_ FROM [Order] orders0_ WHERE orders0_.CustomerId=@p0',N'@p0 uniqueidentifier',@p0='BDB49A49-35B7-43FF-987C-9947014AC5A5'


I have a simple Customer -> Orders mapping.
With the above criteria NH is fetching the customer and ALL orders. To me (a current LLBLGen user and a newbie with NH) this is not expected behavior. I would have thought that only the Customer would have been fetched.

I know I set lazy=false and that if I set lazy=true then it would not be fetched, but I don't want to use lazy loading. The only way I want to get orders from the customer is via the SetFetchMode method on the criteria.

I don't understand the reasoning behind this, can someone explain this behavior to me? Is this the normal behavior? Am I doing something wrong?

Many Thanks,
Joe


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jun 10, 2007 3:52 am 
Regular
Regular

Joined: Thu Nov 23, 2006 10:29 am
Posts: 106
Location: Belgium
Hi,

If you don't want to load automatically the orders, you must set Lazy=true in your mapping file.
Note that you can force the automatic loading of the orders with the SetFetchMode if you specify Lazy=true in your mapping file, but you can not turn off automatic loading if you specify in your mapping file Lazy=false.

In short: set Lazy=true in your mapping file, and set SetFetchMode to Join in your ICriteria when you want to fetch them at once.

_________________
Please rate this post if it helped.

X.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jun 10, 2007 4:50 pm 
Newbie

Joined: Sat Jun 09, 2007 8:22 pm
Posts: 9
Thanks xasp for the reply.

Ok so this is the normal expected behavior.

I understand the lazy attribute and the SetFetchMode method, but I really don't understand the WHY it works like this. I am not trying to be critical mind you, I just want a better understanding of why it works like this so I can explain it to rest of our team. It seems counter intuitive to me. I should not recieve anything I did not ask for.

For example, I don't want to use lazy loading, but I also don't want to fetch all Orders associated with a Customer when all I want is the Customer.Name.

[/b]


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jun 10, 2007 9:41 pm 
Regular
Regular

Joined: Tue Aug 08, 2006 4:28 am
Posts: 96
Location: Hong Kong
Hi jyoung,

Perhaps this thread has a solution for you.

http://forum.hibernate.org/viewtopic.php?t=972214


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 11, 2007 12:57 pm 
Newbie

Joined: Sat Jun 09, 2007 8:22 pm
Posts: 9
Ok, so after rolling this around all weekend I think I figured it out and am quite satisfied with NH now. :D

I am not a big fan of lazy loading but I can deal with it ... I guess. I really had trouble with the WHY NH was fetching all the Orders when I only wanted the Customer.

The conclusion I have come to is to handle aggregates. I don't know if this is what the authors intended, but it works out pretty well I think.

For example, if I am fetching an aggregate root, say an Order, then all the OrderItems should be fetched regardless of whether or not they were asked for, since OrderItem participates in the Order aggregate. The gotcha to me is that now you are defining your aggregates in an XML file instead of the repository. But I really don't think that is such a bad thing.

We had a similar situation where this solution would have fit in rather nicely.

Anyway, posting my conclusion here in case any other NH newbies was struggling with the same question.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.