-->
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: Having NHibernate Return Parameter as Parent (Avoiding N+1)
PostPosted: Sat May 03, 2008 7:02 am 
Beginner
Beginner

Joined: Thu Dec 01, 2005 1:09 pm
Posts: 33
Hibernate version:
1.0.3

Mapping documents:

Code:
<class name="Parent" table="PARENT">
    <id name="ID" type="Int32" column="PARENTID" unsaved-value="-1">
        <generator class="MyGenerator" />
    </id>
</class>


<class name="Child" table="CHILD">

    <id name="ID" type="Int32" unsaved-value="-1" column="CHILDID" >
        <generator class="MyGenerator" />
    </id>

    <many-to-one name="Parent"
                 column="PARENTID"
                 class="Parent"
                 cascade="none"/>

    <property name="SomeProperty" type="String">
        <column name="SOMECOLUMN" length="200" not-null="true" />
    </property>

</class>


Code between sessionFactory.openSession() and session.close():

Code:
Parent p; //cached object from a previous query to the database
string someProperty = "foobar";

string queryString = "from Child c where c.Parent = :parent and c.SomeProperty = :someProperty";
IQuery query = session.CreateQuery( queryString );
query.SetEntity( "parent", parent );
query.SetString( "someProperty", someProperty );


Name and version of the database you are using:


Gupta SQLBase 9.0.1

Debug level Hibernate log excerpt:

Code:
2008-05-03 12:53:17,093 DEBUG NHibernate.Hql.QueryTranslator - HQL: from Child c where c.Parent = :parent and c.SomeProperty = :someProperty
(...)
2008-05-03 12:53:17,108 DEBUG NHibernate.Type.StringType - binding 'foobar' to parameter: 1
2008-05-03 12:53:17,108 DEBUG NHibernate.Engine.Cascades - unsaved-value: -1
2008-05-03 12:53:17,108 DEBUG NHibernate.Type.Int32Type - binding '272' to parameter: 0
(...)
2008-05-03 12:53:17,124 DEBUG NHibernate.Loader.Loader - Hydrating entity: Child#91599
2008-05-03 12:53:17,124 DEBUG NHibernate.Type.Int32Type - returning '272' as column: PAREN2_
2008-05-03 12:53:17,124 DEBUG NHibernate.Type.StringType - returning 'foobar' as column: SOMECOLUMN
2008-05-03 12:53:17,124 DEBUG NHibernate.Loader.Loader - done processing result set (1 rows)
2008-05-03 12:53:17,124 DEBUG NHibernate.Impl.BatcherImpl - Closed Reader, open Readers :0
2008-05-03 12:53:17,124 DEBUG NHibernate.Impl.BatcherImpl - Closed IDbCommand, open IDbCommands :0
2008-05-03 12:53:17,124 DEBUG NHibernate.Loader.Loader - total objects hydrated: 1
2008-05-03 12:53:17,124 DEBUG NHibernate.Impl.SessionImpl - resolving associations for: [Child#91599]
2008-05-03 12:53:17,124 DEBUG NHibernate.Impl.SessionImpl - loading [Parent#272]
2008-05-03 12:53:17,124 DEBUG NHibernate.Impl.SessionImpl - attempting to resolve [Parent#272]
2008-05-03 12:53:17,124 DEBUG NHibernate.Impl.SessionImpl - object not resolved in any cache [Parent#272]
2008-05-03 12:53:17,124 DEBUG NHibernate.Persister.EntityPersister - Materializing entity: Parent#272
2008-05-03 12:53:17,124 DEBUG NHibernate.Impl.BatcherImpl - Opened new IDbCommand, open IDbCommands :1


And then the parent object will be loaded from the database!
Instead, I want NHibernate to use the object I passed as a parameter as I have manually cached it from a previous query to the database.
How can I do that?
Or will I have to drop the many-to-one relation and use a simply Int32 instead?

/Marvin


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 05, 2008 8:28 am 
Expert
Expert

Joined: Thu Dec 14, 2006 5:57 am
Posts: 1185
Location: Zurich, Switzerland
Code:
2008-05-03 12:53:17,124 DEBUG NHibernate.Impl.SessionImpl - loading [Parent#272]
2008-05-03 12:53:17,124 DEBUG NHibernate.Impl.SessionImpl - attempting to resolve [Parent#272]
2008-05-03 12:53:17,124 DEBUG NHibernate.Impl.SessionImpl - object not resolved in any cache [Parent#272]


I assume, you close or clear the session you have used for loading the parent ? If the parent is loaded in the same session and the session is not cleared before the second query, it should work as you want.

_________________
--Wolfgang


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 05, 2008 8:33 am 
Beginner
Beginner

Joined: Thu Dec 01, 2005 1:09 pm
Posts: 33
wolli wrote:
Code:
2008-05-03 12:53:17,124 DEBUG NHibernate.Impl.SessionImpl - loading [Parent#272]
2008-05-03 12:53:17,124 DEBUG NHibernate.Impl.SessionImpl - attempting to resolve [Parent#272]
2008-05-03 12:53:17,124 DEBUG NHibernate.Impl.SessionImpl - object not resolved in any cache [Parent#272]


I assume, you close or clear the session you have used for loading the parent ? If the parent is loaded in the same session and the session is not cleared before the second query, it should work as you want.


Yes. The parent object is never changed during program execution, so I only load it once and pass it to subsequent queries.
Keeping the session open is not an option as my data layer is stateless.


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 05, 2008 9:03 am 
Expert
Expert

Joined: Thu Dec 14, 2006 5:57 am
Posts: 1185
Location: Zurich, Switzerland
You can reattach the parent object to the session:

Code:
sess.Lock(parent, LockMode.None);


If you're definitely sure, that the parent wasn't modified (neither in app nor in db), that should work for you.

Otherwise you have to drop the association and use the plain id instead (as you mentioned).

_________________
--Wolfgang


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 05, 2008 9:04 am 
Beginner
Beginner

Joined: Thu Dec 01, 2005 1:09 pm
Posts: 33
Sounds good, thank you!


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.