-->
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.  [ 8 posts ] 
Author Message
 Post subject: Lazy-loading many-to-one children
PostPosted: Tue Jun 05, 2007 1:42 am 
Beginner
Beginner

Joined: Sun Apr 09, 2006 9:07 pm
Posts: 24
Is it possible to do lazy-loading of many-to-one children (ie. children that are not collections) with NHibernate? I've done a search on this and couldn't find anything, but I'm sure someone must have posted about this before.

Obviously it would require me to modify the code in my class, but that should be fairly simple and I think it could be quite helpful. Something like this:

Code:
class Parent
{
  private Child lazyChild;

  public Child LazyChild
  {
     get
     {
        if (lazyChild == null)
           lazyChild = GetSession().LoadLazyChild(this, "lazyChild");

        return lazyChild;
    }
    set { lazyChild = value; }
  }
}


Of course, it gets more tricky if the child is optional (ie. null is a valid value).


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 05, 2007 2:23 am 
Newbie

Joined: Fri Apr 27, 2007 11:41 am
Posts: 9
lazy loading is the default in hibernate. if you don't change anything by yourself your LazyChild object should actually not be loaded.
you should not place any data access logic in your domain object! just let it as a "normal" property:
Code:
class Parent
{
  private Child lazyChild;

  public Child LazyChild
  {
     get{ return lazyChild; }
     set { lazyChild = value; }
  }
}

and on an other place you can check if it was already loaded:
Code:
if (!NHibernateUtil.IsInitialized(myParent.LazyChild))
{
    NHibernateUtil.Initialize(myParent.LazyChild);
}

for more informations about lazy loading please see the NHibernate documentation.

greez simon[/code]


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 05, 2007 9:24 pm 
Beginner
Beginner

Joined: Sun Apr 09, 2006 9:07 pm
Posts: 24
I found the part about proxies in chapter 14.2 of the manual and that's what NHibernateUtil.Initialize() seems to be for, but it's not really what I'm after. I want the lazy-loading to work with polymorphic classes and don't want to make everything virtual. Can't all that be avoided by simply adding some code around the field access that checks whether the field is initialized?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 06, 2007 9:33 am 
Newbie

Joined: Fri Apr 27, 2007 11:41 am
Posts: 9
do i understand you right that you like to inherit from your Parent class and override the property with a different return type? you could maybe define an Interface for that return type. maybe section 8.1 in the documentation can help you.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 06, 2007 9:16 pm 
Beginner
Beginner

Joined: Sun Apr 09, 2006 9:07 pm
Posts: 24
Sure, I could do that sort of thing, but I don't want to significantly change my code to work with NHibernate. It's NHibernate that should work with my code. So adding some extra code to a property getter is fine, because it's encapsulated and doesn't affect anything else, but defining interfaces, sacrificing polymorphism, making everything virtual, etc. is too much.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 07, 2007 7:51 am 
Newbie

Joined: Fri Apr 27, 2007 11:41 am
Posts: 9
well, of course can you do that (even if i don't think that it is a good practice). you just have to map the id attribute of the LazyChild in the Parent class. additionally your Parent class needs an instance of the hibernate session. the rest is exactly as in your example from the first posting.
Code:
class Parent
{
  private Child lazyChild;
  private int lazyChildId;

  public Child LazyChildId
  {
     get { return lazyChildId; }
    private set { lazyChildId= value; }
  }

  public Child LazyChild
  {
     get
     {
        if (lazyChild == null)
           lazyChild = (Child)GetSession().Get(typeof(Child ), lazyChildId);

        return lazyChild;
    }
    set { lazyChild = value; }
  }
}


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 07, 2007 8:38 pm 
Beginner
Beginner

Joined: Sun Apr 09, 2006 9:07 pm
Posts: 24
Yes, that should work, but then I'm basically losing the benefits of NHibernate like being able to save the child together with the parent (if it's dirty).


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 08, 2007 2:06 am 
Newbie

Joined: Fri Apr 27, 2007 11:41 am
Posts: 9
if you like to save the child together with the parent (with the cascade option), then you have to map the LazyChild property and then it has to be virtual! so you have to decide, map with hibernate or implement your own lazy loading...!
by the way, you can save your child by your self, just implement the ILifecycle interface in your Parenc class and save the child right before the parent is saved.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 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.