Announcement Announcement Module
Collapse
No announcement yet.
Problem with OpenSessionInViewFilter and Hibernate sessions Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Problem with OpenSessionInViewFilter and Hibernate sessions

    I am currently having problems with the OpenSessionInViewFilter together with Hibernate sessions. I need Hibernate sessions to be open for an entire
    HttpRequest as I am most reliant on using the lazy-loading functionality as provided by Hibernate. Currently I am having problems both when running the web-app and through JUnit testcases. In other words, the problem probably lies within the configuration. The application is using Struts in the MVC tier.

    I have read numerous postings to the support forums as well as some blogs touching the subject. However, none of the suggestions seem to be helpful for me. Below I have provided snippets from logs, code and configuration that I consider to be relevant. Any help on the matter will be greatly appreciated!

    Code:
    Log
    
    18:34:56,057 DEBUG TransactionInterceptor:197 - Getting transaction for method 'fetchAllProjects' in class [no.myproj.ProjectService]
    18:34:56,067  INFO JdbcTransactionObjectSupport:60 - JDBC 3.0 Savepoint class is available
    18:34:56,067 DEBUG HibernateTransactionManager:195 - Using transaction object [org.springframework.orm.hibernate.HibernateTransactionManager$HibernateTransactionObject@4a5c78]
    18:34:56,067 DEBUG HibernateTransactionManager:269 - Creating new transaction
    18:34:56,067 DEBUG SessionFactoryUtils:311 - Opening Hibernate session
    18:34:56,067 DEBUG HibernateTransactionManager:371 - Opened new session [net.sf.hibernate.impl.SessionImpl@1fcf790] for Hibernate transaction
    18:34:56,077 DEBUG DataSourceUtils:205 - Setting JDBC connection [org.apache.commons.dbcp.PoolableConnection@1a7789c] read-only
    18:34:56,097 DEBUG HibernateTransactionManager:413 - Exposing Hibernate transaction as JDBC transaction [org.apache.commons.dbcp.PoolableConnection@1a7789c]
    18:34:56,097 DEBUG TransactionSynchronizationManager:147 - Bound value [org.springframework.jdbc.datasource.ConnectionHolder@51ef4e] for key [org.apache.commons.dbcp.BasicDataSource@14e4e31] to thread [main]
    18:34:56,097 DEBUG TransactionSynchronizationManager:147 - Bound value [org.springframework.orm.hibernate.SessionHolder@135f44e] for key [net.sf.hibernate.impl.SessionFactoryImpl@3f4ebd] to thread [main]
    18:34:56,097 DEBUG TransactionSynchronizationManager:199 - Initializing transaction synchronization
    18:34:56,107 DEBUG TransactionSynchronizationManager:122 - Retrieved value [org.springframework.orm.hibernate.SessionHolder@135f44e] for key [net.sf.hibernate.impl.SessionFactoryImpl@3f4ebd] bound to thread [main]
    18:34:56,117 DEBUG TransactionSynchronizationManager:122 - Retrieved value [org.springframework.orm.hibernate.SessionHolder@135f44e] for key [net.sf.hibernate.impl.SessionFactoryImpl@3f4ebd] bound to thread [main]
    18:34:56,157 DEBUG SQL:226 - select project0_.PROSJEKTNR as PROSJEKTNR, project0_.PROSJEKTNAVN as PROSJEKT2_, project0_.KRØSUS_PROSJEKT as KRØSUS_P3_, project0_.HP1 as HP1, project0_.HP2 as HP2, project0_.KM_FRA_1 as KM_FRA_1, project0_.KM_TIL_1 as KM_TIL_1, project0_.KM_FRA_2 as KM_FRA_2, project0_.KM_TIL_2 as KM_TIL_2, project0_.DATO_REGISTRERT as DATO_RE10_, project0_.FRIST_TILTREDELSE as FRIST_T11_, project0_.FRIST_KJØPEKONTRAKT as FRIST_K12_, project0_.GODKJENT_PLANDATO as GODKJEN13_, project0_.PLANTYPE as PLANTYPE, project0_.PROSJEKTTYPE as PROSJEK15_, project0_.ANSVARSNR as ANSVARSNR, project0_.ANLEGG_STARTDATO as ANLEGG_17_, project0_.ANLEGG_FERDIGDATO as ANLEGG_18_, project0_.GRUNNEIERMOTE as GRUNNEI19_, project0_.PROSJEKT_AVSLUTTET as PROSJEK20_, project0_.SAKSBEHANDLER_GRUNN as SAKSBEH21_, project0_.LANDMALER as LANDMALER, project0_.SAKSBEHANDLER_PLAN as SAKSBEH23_, project0_.SAKSBEHANDLER_DRIFT as SAKSBEH24_, project0_.SAKSBEHANDLER_OPPGJØR as SAKSBEH25_, project0_.MERKNAD1 as MERKNAD1, project0_.STATUS_ERVERV as STATUS_27_ from prosjekt_hoved project0_
    Hibernate: select project0_.PROSJEKTNR as PROSJEKTNR, project0_.PROSJEKTNAVN as PROSJEKT2_, project0_.KRØSUS_PROSJEKT as KRØSUS_P3_, project0_.HP1 as HP1, project0_.HP2 as HP2, project0_.KM_FRA_1 as KM_FRA_1, project0_.KM_TIL_1 as KM_TIL_1, project0_.KM_FRA_2 as KM_FRA_2, project0_.KM_TIL_2 as KM_TIL_2, project0_.DATO_REGISTRERT as DATO_RE10_, project0_.FRIST_TILTREDELSE as FRIST_T11_, project0_.FRIST_KJØPEKONTRAKT as FRIST_K12_, project0_.GODKJENT_PLANDATO as GODKJEN13_, project0_.PLANTYPE as PLANTYPE, project0_.PROSJEKTTYPE as PROSJEK15_, project0_.ANSVARSNR as ANSVARSNR, project0_.ANLEGG_STARTDATO as ANLEGG_17_, project0_.ANLEGG_FERDIGDATO as ANLEGG_18_, project0_.GRUNNEIERMOTE as GRUNNEI19_, project0_.PROSJEKT_AVSLUTTET as PROSJEK20_, project0_.SAKSBEHANDLER_GRUNN as SAKSBEH21_, project0_.LANDMALER as LANDMALER, project0_.SAKSBEHANDLER_PLAN as SAKSBEH23_, project0_.SAKSBEHANDLER_DRIFT as SAKSBEH24_, project0_.SAKSBEHANDLER_OPPGJØR as SAKSBEH25_, project0_.MERKNAD1 as MERKNAD1, project0_.STATUS_ERVERV as STATUS_27_ from prosjekt_hoved project0_
    18:34:56,298 DEBUG TransactionSynchronizationManager:122 - Retrieved value [org.springframework.orm.hibernate.SessionHolder@135f44e] for key [net.sf.hibernate.impl.SessionFactoryImpl@3f4ebd] bound to thread [main]
    18:34:56,298  INFO DefaultProjectService:? - Fetched [4] projects
    18:34:56,298 DEBUG TransactionInterceptor:240 - Invoking commit for transaction on method 'fetchAllProjects' in class [no.myproj.ProjectService]
    18:34:56,298 DEBUG HibernateTransactionManager:498 - Triggering beforeCommit synchronization
    18:34:56,298 DEBUG HibernateTransactionManager:513 - Triggering beforeCompletion synchronization
    18:34:56,298 DEBUG HibernateTransactionManager:375 - Initiating transaction commit
    18:34:56,308 DEBUG HibernateTransactionManager:460 - Committing Hibernate transaction on session [net.sf.hibernate.impl.SessionImpl@1fcf790]
    18:34:56,308 DEBUG HibernateTransactionManager:543 - Triggering afterCompletion synchronization
    18:34:56,308 DEBUG TransactionSynchronizationManager:239 - Clearing transaction synchronization
    18:34:56,308 DEBUG TransactionSynchronizationManager:170 - Removed value [org.springframework.orm.hibernate.SessionHolder@135f44e] for key [net.sf.hibernate.impl.SessionFactoryImpl@3f4ebd] from thread [main]
    18:34:56,308 DEBUG TransactionSynchronizationManager:170 - Removed value [org.springframework.jdbc.datasource.ConnectionHolder@51ef4e] for key [org.apache.commons.dbcp.BasicDataSource@14e4e31] from thread [main]
    18:34:56,308 DEBUG DataSourceUtils:251 - Resetting read-only flag of connection [org.apache.commons.dbcp.PoolableConnection@1a7789c]
    18:34:56,318 DEBUG HibernateTransactionManager:542 - Closing Hibernate session [net.sf.hibernate.impl.SessionImpl@1fcf790] after transaction
    18:34:56,328 DEBUG SessionFactoryUtils:649 - Closing Hibernate session
    18:34:56,338 ERROR LazyInitializationException:25 - Failed to lazily initialize a collection - no session or session was closed
    net.sf.hibernate.LazyInitializationException: Failed to lazily initialize a collection - no session or session was closed
    	at net.sf.hibernate.collection.PersistentCollection.initialize(PersistentCollection.java:209)
    	at net.sf.hibernate.collection.PersistentCollection.read(PersistentCollection.java:71)
    	at net.sf.hibernate.collection.Set.size(Set.java:106)
    	at no.myproj.Project.toString(Unknown Source)
    	at org.apache.log4j.or.DefaultRenderer.doRender(DefaultRenderer.java:26)
    	at org.apache.log4j.or.RendererMap.findAndRender(RendererMap.java:70)
    	at org.apache.log4j.spi.LoggingEvent.getRenderedMessage(LoggingEvent.java:288)
    	at org.apache.log4j.helpers.PatternParser$BasicPatternConverter.convert(PatternParser.java:395)
    	at org.apache.log4j.helpers.PatternConverter.format(PatternConverter.java:56)
    	at org.apache.log4j.PatternLayout.format(PatternLayout.java:495)
    	at org.apache.log4j.WriterAppender.subAppend(WriterAppender.java:292)
    	at org.apache.log4j.WriterAppender.append(WriterAppender.java:150)
    	at org.apache.log4j.AppenderSkeleton.doAppend(AppenderSkeleton.java:221)
    	at org.apache.log4j.helpers.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:57)
    	at org.apache.log4j.Category.callAppenders(Category.java:187)
    	at org.apache.log4j.Category.forcedLog(Category.java:372)
    	at org.apache.log4j.Category.info(Category.java:674)
    	at no.myproj.ProjectTestCase.testGetAll(ProjectTestCase.java:37)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:324)
    	at junit.framework.TestCase.runTest(TestCase.java:154)
    	at junit.framework.TestCase.runBare(TestCase.java:127)
    	at junit.framework.TestResult$1.protect(TestResult.java:106)
    	at junit.framework.TestResult.runProtected(TestResult.java:124)
    	at junit.framework.TestResult.run(TestResult.java:109)
    	at junit.framework.TestCase.run(TestCase.java:118)
    	at junit.framework.TestSuite.runTest(TestSuite.java:208)
    	at junit.framework.TestSuite.run(TestSuite.java:203)
    	at junit.textui.TestRunner.doRun(TestRunner.java:116)
    	at com.intellij.rt.execution.junit2.IdeaJUnitAgent.doRun(IdeaJUnitAgent.java:57)
    	at junit.textui.TestRunner.start(TestRunner.java:172)
    	at com.intellij.rt.execution.junit.TextTestRunner2.startRunnerWithArgs(TextTestRunner2.java:23)
    	at com.intellij.rt.execution.junit2.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:97)
    	at com.intellij.rt.execution.junit2.JUnitStarter.main(JUnitStarter.java:31)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:324)
    	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:78)
    18:34:56,358 DEBUG TransactionSynchronizationManager:122 - Retrieved value [org.springframework.orm.hibernate.SessionHolder@2b349d] for key [net.sf.hibernate.impl.SessionFactoryImpl@2d7440] bound to thread [main]
    18:34:56,358 DEBUG TransactionSynchronizationManager:170 - Removed value [org.springframework.orm.hibernate.SessionHolder@2b349d] for key [net.sf.hibernate.impl.SessionFactoryImpl@2d7440] from thread [main]
    18:34:56,358 DEBUG SessionFactoryUtils:649 - Closing Hibernate session
    Code:
    TestCase
    
    public class ProjectTestCase extends TestCase{
    
        private SessionFactory sessionFactory;
    
        public void setUp() throws Exception {
            super.setUp();
            sessionFactory = (SessionFactory) findSessionFactory();
            Session s = sessionFactory.openSession();
            TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(s));
        }
        
        public void testGetAll() throws Exception {
            List allProjects = service.fetchAllProjects();
            assertNotNull("Received null value for projects!", allProjects);
            assertTrue("Unexpected project state!", allProjects.size() > 0);
            for (Iterator i = allProjects.iterator(); i.hasNext();) {
                log.info(i.next());
            }
        }    
    
        public void tearDown() throws Exception {
            super.tearDown();
            SessionHolder holder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);
            Session s = holder.getSession();
            s.flush();
            TransactionSynchronizationManager.unbindResource(sessionFactory);
            SessionFactoryUtils.closeSessionIfNecessary(s, sessionFactory);
        }
    }
    Code:
    Service implementation
    
    public class DefaultProjectService implements ProjectService {
    
        private ProjectDAO projectDAO;
    
        public void setProjectDAO(ProjectDAO projectDAO) {
            this.projectDAO = projectDAO;
        }
    
        public List fetchAllProjects() {
            return projectDAO.fetchAll();
        }
    }
    Code:
    DAO implementation
    
    public class ProjectDAOImpl extends HibernateDaoSupport implements ProjectDAO {
        public List fetchAll() {
            return getHibernateTemplate().find("from no.myproj.Project");
        }
    }
    Code:
    Hibernate mapping
    
    <hibernate-mapping>
        <class
            name="no.myproj.Project"
            table="prosjekt_hoved"
            dynamic-update="false"
            dynamic-insert="false"
            select-before-update="false">
            <id
                name="projectId"
                column="PROSJEKTNR"
                type="int">
                <generator class="increment">
                </generator>
            </id>
    
            <property
                name="projectName"
                type="string"
                update="true"
                insert="true"
                access="property"
                column="PROSJEKTNAVN"/>
    
            <set
                name="properties"
                lazy="true"
                inverse="false"
                cascade="all"
                sort="unsorted">
                  <key
                      column="EIENDOMSNR"
                  >
                  </key>
                  <one-to-many
                      class="no.myproj.Property"
                  />
            </set>
        </class>
    </hibernate-mapping>
    Code:
    spring.xml
    
    <beans>
        <bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
            <property name="mappingResources">
                <list>
                    <value>no/myproj/Project.hbm.xml</value>
                    <value>no/myproj/Property.hbm.xml</value>
                </list>
            </property>
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.dialect">net.sf.hibernate.dialect.OracleDialect</prop>
                    <prop key="hibernate.show_sql">true</prop>
                </props>
            </property>
            <property name="dataSource">
                <ref bean="dataSource"/>
            </property>
        </bean>
    
        <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
            <property name="driverClassName">
                <value>oracle.jdbc.driver.OracleDriver</value>
            </property>
            <property name="url">
                <value>jdbc&#58;oracle&#58;thin&#58;@127.0.0.1&#58;1521&#58;ORCL</value>
            </property>
            <property name="username">
                <value>username</value>
            </property>
            <property name="password">
                <value>password</value>
            </property>
        </bean>
    
        <bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
            <property name="sessionFactory">
    	    <ref local="sessionFactory"/>
    	</property>
        </bean>
    
        <bean id="projectDAO" class="no.myproj.ProjectDAOImpl">
            <property name="sessionFactory">
                <ref local="sessionFactory"/>
            </property>
        </bean>
    
        <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
            <property name="transactionManager">
                <ref bean="transactionManager"/>
            </property>
            <property name="transactionAttributeSource">
                <value>
                    no.myproj.ProjectService.fetch*=PROPAGATION_REQUIRED,readOnly,-Exception
                    no.myproj.ProjectService.save=PROPAGATION_REQUIRED,-Exception
                    no.myproj.ProjectService.delete=PROPAGATION_REQUIRED,-Exception
                </value>
            </property>
        </bean>
    
        <bean id="projectTarget" class="no.myproj.DefaultProjectService">
            <property name="projectDAO">
                <ref bean="projectDAO"/>
            </property>
        </bean>
    
        <bean id="projectService" class="org.springframework.aop.framework.ProxyFactoryBean">
            <property name="proxyInterfaces">
                <value>no.myproj.ProjectService</value>
            </property>
            <property name="interceptorNames">
                <list>
                    <value>transactionInterceptor</value>
                    <value>projectTarget</value>
                </list>
            </property>
        </bean>
    </beans>

  • #2
    Were you able to resolve this issue? I am having the same problem.

    Comment


    • #3
      Where exactly is configured your OpenSessionInViewFilter? Obviously the session is closed before your actual test which means that probably the HibernateTemplate used creates a new session during the callback and then close it.
      Have you looked at the integration support test in Hibernate (check out the reference documentation at the end).

      Comment


      • #4
        Sorry for the slow response on this one.

        The reply from Costin is obviously correct. The root cause is that the session is closed right after invoking the data access i.e. the dao implementation.

        The problem is downright impossible to identify for non-domain experts - and I personally believe a similar problem has been experienced by many others. The Hibernate configuration is incorrect. The key reference on the many-side referers to the primary key of that side and not its foreign key to the one-side.

        As mentioned in my original post, the application uses Struts as an MVC framework. Spring's plugin for Struts was used in the struts-config.xml and this gave a most unfortunate side effect. The application context was loaded twice - also resulting in a LazyInitializationException. However, this has absolutely nothing to do with the problems I originally described but it is worth noting anyhow.

        Comment


        • #5
          I have exactly the same problem and I don't use Struts as MVC. My config is:

          * Spring MVC
          * Transaction with AOP and Annotations (jdk5)
          * Hibernate 3.1rc2 (because I want to use annotations)

          Maybe it is because Hibernate 3.1rc2 has not been tested yet with Spring.

          Any help would be welcome. The OpenViewFilter facility would avoid me to intitialize my collections in the DAO with getHibernateTemplate().initialize(user.getroles())

          Thanks

          Comment


          • #6
            Do you experience the same problem both in your integration tests as well as directly from the web application?

            If you're having problems in your web application only make sure your web.xml is configured correctly. It should be something like this:

            <code>
            <web-app>
            <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath*:spring-common-context.xml,classpath*:spring-dao-context.xml,classpath*:spring-datasources-context.xml,classpath*:spring-services-context.xml</param-value>
            </context-param>

            <listener>
            <listener-class>org.springframework.web.context.ContextLoade rListener</listener-class>
            </listener>
            </web-app>
            </code>

            You say you're using Spring MVC so I take it that you inject services directly to your controller classes. In that case you are definetely using the same context as you have defined in your web.xml.

            In other cases (i.e. using Spring and Struts without mapping action implementations to Spring managed beans) one should make sure that a new context is not created at some point. To ensure this, use WebApplicationContextUtils.getRequiredWebApplicati onContext(ServletContext ccx) in order to fetch a reference to the application context.

            Comment

            Working...
            X