-->
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.  [ 2 posts ] 
Author Message
 Post subject: LazyInitializationExceptions using Hibernate/Spring/Oracle
PostPosted: Wed Jun 06, 2007 10:55 pm 
Newbie

Joined: Wed Jun 06, 2007 10:51 pm
Posts: 1
Hi all;

This seems to be a common issue, but all my searching and reading has not found the particular solution that works for us.

We're trying to use Hibernate as our persistance layer for a large enterprisey system. We have annotated POJOs generated from a database using the maven appfuse plugin. We are also trying to follow Appfuse's design, namely:

- Annotated POJOs
- DAO layer (Hibernate)
- Manager layer (abstracts actual DAO implementation from users)

We are trying to use Spring to wire everything together, but running into the dreaded LazyInitializationException: no session or session was closed.

We thought we could just use Spring's declarative transactions to handle everything for us, but we cannot seem to get things working correctly, either inside of a web container or running standalone. I've read quite a bit about the OpenSessionInViewFilter, and we may pursue that for use on our webapp (running on Weblogic Server), but we need our Hibernate configuration to run stand-alone as well.

Stepping through debugger (or log files), it seems that the sequence of events is something like:
- Spring creates a transaction
- Spring creates a Hibernate Session
- JDBC connection established
- SQL run, collections are lazy loaded/proxied
- HibernateTemple does NOT close the session
- Spring thinks the transaction is complete
- Spring closes the Hibernate Session
- Spring closes the transaction
- User tries to access a lazy loaded collection and gets an exception

We're using Hibernate3, Spring 2.0, connecting to an Oracle database. Eventually we want to be able to run this on a Weblogic Server 9.2.

Thanks in advance for any advice!

Sample code:

Code:
      // ApplicationContextFactory statically loads our ClassPathXmlApplicationContext and gives it back to you
      MyManagerImpl myManager = (MyManagerImpl) ApplicationContextFactory
            .getBean("myManager");
      MyObject obj = myManager.get( 123L );
      // Now Spring has closed the Hibernate Session

      // Single property access is just fine
      obj.getName();
      // collection access throws LazyInitializationErro
      obj.getOtherObject().getSomeProperty();



applicationContext.xml:

Code:
   <!-- SessionFactory for hibernate -->
   <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
      <property name="dataSource" ref="dataSource"/>
      <property name="configLocation" value="classpath:hibernate.cfg.xml"/>
      <property name="hibernateProperties">
         <value>
            hibernate.default_schema=${hibernate.default_schema}
         </value>
      </property>
   </bean>

   <!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
   <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
      <property name="sessionFactory" ref="sessionFactory"/>
   </bean>

   <!-- wrap anything from manager package in a Spring transaction -->
   <aop:config>
      <aop:advisor id="managerTx" advice-ref="txAdvice" pointcut="execution(* *..manager.*Manager.*(..))" order="2"/>
   </aop:config>
   
   <tx:advice id="txAdvice">
      <tx:attributes>
         <tx:method name="*"/>
      </tx:attributes>
   </tx:advice>

   <!-- Enable @Transactional support -->
   <tx:annotation-driven/>

   <!-- Enable @AspectJ support -->
   <aop:aspectj-autoproxy/>


   <!-- sample DAO -->
   <bean id="myDao" class="com.myapp.db.dao.hibernate.MyHibernateDao">
      <property name="sessionFactory">
         <ref local="sessionFactory" />
      </property>
   </bean>

   <!-- sample Manager -->
   <bean id="myManager" class="com.myapp.db.manager.impl.MyManagerImpl">
      <constructor-arg ref="myDao" />
   </bean>


MyObject:

Code:
@Entity
@Table(name="MY_OBJECTS")
public class MyObject extends BaseObject implements Serializable {
   private Long idPk;
   private String name;
   private OtherObject otherObject;
   private Set<SomeOtherObject> someOtherObjects = new HashSet<SomeOtherObjects>(0);

   @Id
   @Column(name="MY_OBJECT_ID_PK", unique=true, nullable=false, precision=18, scale=0)
   public Long getIdPk() {return this.idPk;}
   ...

   @ManyToOne(fetch=FetchType.LAZY)
   public OtherObject getOtherObject() {return this.otherObject;}
   ...

   @OneToMany(cascadeType=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="myObject")
   public Set<SomeOtherObject> getSomeOtherObjects() {return this.someOtherObjects;}
   ...
}


MyHibernateDao:

Code:
   public class MyHibernateDao
     extends GenericDaoHibernate<MyObject, Long>
     implements MyDao
   {
     public  MyHibernateDao() {
      super(MyObject.class);
     }
   }


MyManagerImpl:

Code:
   public class MyManagerImpl
     extends GenericManagerImpl<MyObject, Long>
     implements MyManager
   {
     private MyDao m_MyDao;

     public MyManagerImpl(MyDao a_MyDao) {
      super(a_MyDao);
      m_MyDao = a_MyDao;
     }
   }


GenericDaoHibernate:

Code:
public class GenericDaoHibernate<T, PK extends Serializable> extends HibernateDaoSupport implements GenericDao<T, PK> {

  protected final Log log = LogFactory.getLog(getClass());

  private Class<T> persistentClass;

  public GenericDaoHibernate() {}

  public GenericDaoHibernate(Class<T> persistentClass) {
    this.persistentClass = persistentClass;
  }

  public boolean exists(PK id) {
    T entity = (T) super.getHibernateTemplate().get(this.persistentClass, id);
    if (entity == null) {
      return false;
    } else {
      return true;
    }
  }

  public T get(PK id) {
    T entity = (T) super.getHibernateTemplate().get(this.persistentClass, id);

    if (entity == null) {
      // log.warn("Uh oh, '" + this.persistentClass + "' object with id '"
      // + id + "' not found...");
      throw new ObjectRetrievalFailureException(this.persistentClass, id);
    }

    return entity;
  }

  public List<T> getAll() {
    return super.getHibernateTemplate().loadAll(this.persistentClass);
  }

  public void remove(PK id) {
    super.getHibernateTemplate().delete(this.get(id));
  }

  public void save(T object) {
    super.getHibernateTemplate().saveOrUpdate(object);
  }
}


GenericManagerImpl:

Code:
public class GenericManagerImpl<T, PK extends Serializable> implements GenericManager<T, PK> {
  protected final Log log = LogFactory.getLog(getClass());
  protected GenericDao<T, PK> genericDao;

  public GenericManagerImpl() {}

  public GenericManagerImpl(GenericDao<T, PK> genericDao) {
    this.genericDao = genericDao;
  }

  public List<T> getAll() {
    return genericDao.getAll();
  }

  public T get(PK id) {
    return genericDao.get(id);
  }

  public boolean exists(PK id) {
    return genericDao.exists(id);
  }

  public void save(T object) {
    genericDao.save(object);
  }

  public void remove(PK id) {
    genericDao.remove(id);
  }
}


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 07, 2007 9:48 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
I don't know much about Spring so I can't help. The framework that really solved the LIE issue is JBoss Seam (it has been designed with that in mind - and many other things :-) ).

_________________
Emmanuel


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