-->
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: Problems with Lazy initialization
PostPosted: Fri Jul 23, 2004 12:16 pm 
Newbie

Joined: Wed Jul 14, 2004 8:47 pm
Posts: 4
Location: Mexico City
I've been trying to access a lazy initialized set from a class. If I didn't understood wrong, hibernate was supposed to take care about bringing from the database the objects when I called the getSet of the Business Object. I don't know if I'm missing something here, I created a series of interfaces so the rest of my system layers could access the Object, and I implement those in the business object itself (as it should be), but every single time I want to access the data in the sets, I get a:
Failed to lazily initialize a collection - no session or session was closed

I am working with the spring framework and it's supposed to take care of the session managing, si I really don't think the problem is the session getting closed, I think is that I'm skipping maybe some connection between the Business Object and the DAO.

So my question is, can somebody give me a clue on how to wire everything up.


Here's how I have everything wired up.

BaseClass
BaseClassDAO extends _RootDAO

IClass
ClassManager

Class implements IClass
ClassDAO implements ClassManager

here are my mappings:

Code:
   
<class name="Usuario" table="usuario">
  <id name="numerostr" type="java.lang.String" column="numerostr">
     <generator class="assigned"/>
  </id>
...
<set name="perfils" table="rusuario_perfil" lazy="true">
   <key column="numerostr"/>
   <many-to-many class="portal.data.Cperfil" column="idperfilint"/   
</set>
...



Any kind of help will be greatly appreciated.


Top
 Profile  
 
 Post subject: Hibernate documenttion--maybe this 'll help you
PostPosted: Fri Jul 23, 2004 12:20 pm 
Beginner
Beginner

Joined: Thu Apr 29, 2004 4:03 pm
Posts: 40
6.5. Lazy Initialization

Collections (other than arrays) may be lazily initialized, meaning they load their state from the database only when the application needs to access it. Initialization happens transparently to the user so the application would not normally need to worry about this (in fact, transparent lazy initialization is the main reason why Hibernate needs its own collection implementations). However, if the application tries something like this:

s = sessions.openSession();
User u = (User) s.find("from User u where u.name=?", userName, Hibernate.STRING).get(0);
Map permissions = u.getPermissions();
s.connection().commit();
s.close();

Integer accessLevel = (Integer) permissions.get("accounts"); // Error!

It could be in for a nasty surprise. Since the permissions collection was not initialized when the Session was committed, the collection will never be able to load its state. The fix is to move the line that reads from the collection to just before the commit. (There are other more advanced ways to solve this problem, however.)

Alternatively, use a non-lazy collection. Since lazy initialization can lead to bugs like that above, non-laziness is the default. However, it is intended that lazy initialization be used for almost all collections, especially for collections of entities (for reasons of efficiency).

Exceptions that occur while lazily initializing a collection are wrapped in a LazyInitializationException.

Declare a lazy collection using the optional lazy attribute:

<set name="names" table="NAMES" lazy="true">
<key column="group_id"/>
<element column="NAME" type="string"/>
</set>

In some application architectures, particularly where the code that accesses data using Hibernate, and the code that uses it are in different application layers, it can be a problem to ensure that the Session is open when a collection is initialized. They are two basic ways to deal with this issue:

*

In a web-based application, a servlet filter can be used to close the Session only at the very end of a user request, once the rendering of the view is complete. Of course, this places heavy demands upon the correctness of the exception handling of your application infrastructure. It is vitally important that the Session is closed and the transaction ended before returning to the user, even when an exception occurs during rendering of the view. The servlet filter has to be able to access the Session for this approach. We recommend that a ThreadLocal variable be used to hold the current Session (see chapter 1, Section 1.4,


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 23, 2004 12:51 pm 
Newbie

Joined: Wed Jul 14, 2004 8:47 pm
Posts: 4
Location: Mexico City
Thanx for the quick response hiberman, but I've read that a couple of times but it just don't seem to fit with my actual problem. In the documentation they propose a possible solution for a multi layered application,and also for a web based, But the thing is that I'm not using Servlets to control my session, I'm using the Spring Framework. And for the other solution, I can't see how can I apply it, it is supposed that when you access the bussiness object hibernate must know how to do it, but how can I tell hibernate where to find the session, if I'm accessing the business object not the DAO.

Cheers, Aztek


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 23, 2004 3:59 pm 
Beginner
Beginner

Joined: Fri Mar 26, 2004 8:19 am
Posts: 49
Aztek, I think that the Spring term you want to search for is OpenSessionInView. I'm not a Spring user, but that's one of the patterns people keep talking about.

How are you handling your sessions now? When is it closed?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 23, 2004 8:04 pm 
Beginner
Beginner

Joined: Wed Jul 21, 2004 12:28 pm
Posts: 27
Location: New York
this will do the trick for you:


Code:


public class HibernateParentDAO extends HibernateDaoSupport {

  :
  :

  public Set getChildren (final Parent arg) {
     Parent p = null;

     p = (Parent) this.getHibernateTemplate ().execute (
              new HibernateCallback() {
                 public Object doInHibernate(Session session)
                                               throws HibernateException {
                    Parent p = (Parent) session.load (Parent.class, arg.getId ());
                    p.getChildren ().size ();
                    return p;
                 }
               });
       
     if (p.getChildren () == null) {
       return new HashSet ();
     } else {
       return p.getChildren ();
     }
       
  }

  :
  :

}


This will not work:

Code:
  public Set getChildren (final Parent arg) {
     Parent p = null;

     p = (Parent) this.getHibernateTemplate ()
                             .load (Parent.class, arg.getId ());
     if (p.getChildren () == null) {
       return new HashSet ();
     } else {
       return p.getChildren ();
     }
  }


don't even bother :-) it throws lazy collection initialization exception

HTH,
Alex.


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.