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:

                // 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:

        <!-- 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:

@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:

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

MyManagerImpl:

        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:

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:

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);
  }
}


-- 
View this message in context: 
http://www.nabble.com/LazyInitializationExceptions-using-Hibernate-Spring-Oracle-tf3881565s2369.html#a11001124
Sent from the AppFuse - User mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to