views:

2581

answers:

4

Hello! I have a problem with LazyInitializationException even though I'm using openSessionInViewInterceptor. I've read so many posts about that topic and I've tried three or four different approaches to it.

First thing is that I don't want to set to false the lazzy attribute in the Hibernate configuration file. So, I want an actual solution to that problem. I'm using Spring 2.5, Hibernate 3, Netbeans and Tomcat.

My implementation is as follows:

servlet.xml

<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="interceptors">
            <list>
                <ref bean="openSessionInViewInterceptor" />
            </list>
        </property>
        <property name="mappings">
            <props>
                <prop key="/index.htm">indexController</prop>
            </props>
        </property>
 </bean>
 <bean id ="openSessionInViewInterceptor" name="openSessionInViewInterceptor"
    class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
    <property name="sessionFactory">
        <ref bean="sessionFactory" />
    </property>
</bean>

applicationContext.xml

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource">
            <ref local="dataSource"/>
        </property>
        <property name="mappingResources">
            <list>
                <value>TasquesDAOHibernate/Model/Tasca.hbm.xml</value>
                <value>TasquesDAOHibernate/Model/TipusTasca.hbm.xml</value>
                <value>TasquesDAOHibernate/Model/Prioritat.hbm.xml</value>
                <value>TasquesDAOHibernate/Model/Persona.hbm.xml</value>
                <value>TasquesDAOHibernate/Model/EstatTasca.hbm.xml</value>
                <value>TasquesDAOHibernate/Model/Usuari.hbm.xml</value>
                <value>TasquesDAOHibernate/Model/LogActivitat.hbm.xml</value>
                <value>TasquesDAOHibernate/Model/ObjecteSIPANUsuari.hbm.xml</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.jdbc.batch_size">0</prop>
            </props>
        </property>
    </bean>


    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory">
            <ref local="sessionFactory"/>
        </property>
    </bean>

    <bean id="tasquesDAO" class="TasquesDAOHibernate.TasquesDAOHibernate">
        <property name="sessionFactory">
            <ref local="sessionFactory"/>
        </property>
    </bean>

<bean id="tasquesService" name="tasquesService" class="Tasques_www.service.TasquesService" >
        <property name="tasquesDAO">
            <ref local="tasquesDAO"/>
        </property>
        <property name="transactionManager" ref="transactionManager"/>
    </bean>

TasquesService.java

public List<Tasca> getTasques() {
        List<Tasca> tasques = (List)this.transactionTemplate.execute(new           TransactionCallback() {

            public Object doInTransaction(TransactionStatus status) {
                Object tasques = tasquesDAO.getTasques();
                return tasques;
            }
        });
        return tasques;
    }

TasquesDAOHibernate.java

public List<Tasca> getTasques() {
        Session session = this.sessionFactory.getCurrentSession();
        try{
            Query query = session.createQuery("SELECT element FROM Tasca AS element");
            List result = query.list();
            return result;
        }catch(HibernateException ex){
            return null;
        }
    }

I think those are the important files. I've tried lots of things and I'm always getting LazyInitializationException or

org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here ...

I don't know which one is worst.

Thanks in advance!

A: 

I think you need a filter at the web.xml level:

<filter>
 <filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
 <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter>

Only this way will spring be able to know when your view is being rendered.

Miguel Ping
The interceptor should have the same effect as the filter, assuming that the controller is forwarding to the view.
skaffman
I believe there was a bug in some spring version with the interceptor, so the filter was preferred. Not sure, though.
Miguel Ping
A: 

You can try using an interceptor native from Spring take a look in mine

<bean id="transactionManager"
 class="org.springframework.orm.hibernate3.HibernateTransactionManager">
 <property name="sessionFactory">
  <ref bean="sessionFactory" />
 </property>
</bean>

<bean id="txAttributeSource"
 class="org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource">
 <property name="properties">
  <props> <!-- this catches every method with the interceptor-->
   <prop key="*">PROPAGATION_REQUIRED</prop>
  </props>
 </property>
</bean>

<bean id="txInterceptor"
 class="org.springframework.transaction.interceptor.TransactionInterceptor">
 <property name="transactionManager">
  <ref local="transactionManager" />
 </property>
 <property name="transactionAttributeSource">
  <ref local="txAttributeSource" />
 </property>
</bean>

<bean id="autoProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
 <property name="interceptorNames">
  <list>
   <idref local="txInterceptor" />
  </list>
 </property>
 <property name="beanNames">
  <list> <!--this proxies every bean with the especified pattern -->
   <value>*BL</value>
  </list>
 </property>
</bean>
Thiago Diniz
And how would this fix the problem?
skaffman
A: 

To keep your session open during the entire request, you'll need to add Spring's OpenSessionInViewFilter to your web.xml. This one is specific to hibernate3:

<filter>
    <filter-name>OpenSessionInViewFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
Clay
+1  A: 

The problem is your use of the transaction manager: This will start a new session and since you manually opened it, it will also close it. You need to configure your transaction management using Springs configuration, so all components will work correctly together.

Use a transaction interceptor on your business layer (TasqueService).

Maarten Winkels