Page 1 of 2 12 LastLast
Results 1 to 10 of 14

Thread: LazyInitializationException with Spring+Hibernat

  1. #1

    Default LazyInitializationException with Spring+Hibernat

    Hi,

    I am using Spring and hibernate with POJOS. I configured Hibernate with Spring and configured Pojos with hibernate.

    I have few collections that i want to be lazily loaded. I have defined these colllections as lazy="false" in hbm files. I have a spring transaction attached to every method of manager where i get these objects. For eg: I am having a domain Object User and it has a Collection of Roles. Role here is another domain object and this collection is lazily loaded. I am having AuthorisationFacade that gets this user object using the DAO pattern. These DAO's are nothing but the HibernateDAOSupport enabled. Using hibernateTemplate i am getting the User object from the DATAAccess layer. I am having a method called getUser(pk) in AuthorisationManager that calls the DAO to get the User object from the dataaceess layer. This AuthorisationFacade is accessible to User Interface and when user interface gets this User object and tries to access the Collection of Roles it gets the error LazyInitializationException. I know the sesssion is terminated here so when it tries to access the lazily loaded collections it tries to connect the session and there is no session so it gives this error.

    I am sure there must be a way to get these lazily loaded collections using Spring and Hibernate. Does anyone knows this.

    Your anwsers are welcome here..

  2. #2
    Join Date
    Nov 2006
    Location
    Germany
    Posts
    452

    Default

    Hi,

    AFAIK you have to use the OpenSessionInViewFilter if you want to lazily load your collections, while rendering the view

    http://www.springframework.org/docs/...iewFilter.html

    Or do you want to eager load all collections and avoid the usage of opensessioninviewfilter ?

    Best regards
    lyserg

  3. #3
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    One thing is where you are trying to lazy load it. If it is indeed in the view, OSIV or eager loading is your best bet. If it's just generally within the application then transactions would help the session management e.g. adding it to the service layer.

    BTW, if you set lazy="false" then it won't be lazy loading.
    http://www.springframework.org/docs/...ansaction.html

  4. #4

    Default

    Hi,

    Thanks for the reply. But my domain objects are simple POJOS. Let me more elloberate with this problem.

    My Dataacess layer is only ORM dependent layer here. The domain object is passed to the User Interface and this object tries to access the collection on UI. Also I cant make my objects as Spring or Hibernate Aware.

  5. #5
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    If it's the UI as previously stated, either OSIV or eager loading is what you are looking for (see options below).
    http://www.springframework.org/docs/...iewFilter.html

    #1. Set assocation lazy=false (wouldn't do that unless its the only option)

    #2. Eagerly load in HQL or Criteria API
    http://www.hibernate.org/hib_docs/v3...queryhql-joins
    http://www.hibernate.org/hib_docs/v3...ynamicfetching

    #3. Use HibernateTemplate.initialize()
    http://www.hibernate.org/hib_docs/v3...a.lang.Object)

    #4. Walk the association inside the session (i.e. collection.size())
    http://www.hibernate.org/hib_docs/v3...-fetching-lazy

  6. #6

    Default

    Try this bro,

    Code:
    public interface PostLoadHibernateCallback
    {
        public Object postLoad(Object entity,  Session session);
    }
    
    public class UserDaoImpl extends HibernateDaoSupport
    {
         @SuppressWarnings("unchecked")
        public User getUserByPrimaryKey(final Class clazz, final Long pk,
                final PostLoadHibernateCallback callback, final LockMode lockMode)
        {
            if (clazz == null)
                throw new IllegalArgumentException("clazz can not be null");
    
            return (User) this.getHibernateTemplate().execute(new HibernateCallback()
            {
                public Object doInHibernate(Session session) throws HibernateException
                {
                                    User user = null;
                    if (lockMode != null)
                    {
                        user = (User) session.get(clazz, pk, lockMode);
                        return callback.postLoad(obj, session);
                    }
                    else
                    {
                        user = (User) session.get(clazz, pk);
                        return callback.postLoad(obj, session);
                    }
                }
            }, true);
        }
    
    }
    You can access roles collection of user class in postLoad method of callback interface or if you dont like this interface thingy then do your stuff in doInHibernate method, and thats it....

    Cheers,

    Imran Sarwar

  7. #7
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    Isn't it just easier to use Hibernates features? What is the 'obj' variable supposed to be here?

  8. #8

    Default

    This approach is there because when you have enabled lazyloading and using spring hibernate HibernateTemplate. Spring opens the hibernate session and then closes it as soon as the call returns from the data access method from the spring ORM layer and as a result when you access the method in your POJO it throws LazyInitializationException. The callback interface PostLoadHibernateCallback is there to keep the session open and give you the control so that you can access the POJO method and the obj is the object of the class that you passed to the getUserByPrimaryKey method, in your case it will be a User object. I don't think there is any other option if you want to use spring hibernate support and want lazy loading. If you are just using hibernate at the data access layer then of course you can do it more easily

    Hope it helps

    Regards,
    Imran

  9. #9
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    How about OpenSessionInView or simply using transactions?

  10. #10

    Default

    Hi sanjaybahrani,

    You have enabled lazy fetching and retrieving that object by its access method out side of transaction. It could be three solutions

    Uses
    Hibernate.initialize();
    or access that in transaction scope.
    or Hbm set lazy ="false"

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •