Announcement Announcement Module
Collapse
No announcement yet.
Hibernate Session closed despite OpenSessionInViewFilter Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Hibernate Session closed despite OpenSessionInViewFilter

    Hi,

    I have a problem that is driving me nuts. I have configured the OpenSessionInViewFilter like this in my web.xml:

    Code:
        <filter>
            <filter-name>sitemesh</filter-name>
            <filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class>
        </filter>
        <filter>
            <filter-name>hibernate</filter-name>
            <filter-class>org.springframework.orm.hibernate.support.OpenSessionInViewFilter</filter-class>
            <init-param>
                <param-name>singleSession</param-name>
                <param-value>false</param-value>
            </init-param>
        </filter>
        
        <filter-mapping>
            <filter-name>sitemesh</filter-name>
            <url-pattern>/abp/action/*</url-pattern>
            <dispatcher>REQUEST</dispatcher>
            <dispatcher>FORWARD</dispatcher>
            <dispatcher>ERROR</dispatcher>
        </filter-mapping>
        <filter-mapping>
            <filter-name>hibernate</filter-name>
            <url-pattern>/abp/action/*</url-pattern>
            <dispatcher>REQUEST</dispatcher>
            <dispatcher>FORWARD</dispatcher>
        </filter-mapping>
    
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
    
        <servlet>
            <servlet-name>action</servlet-name>
            <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet>
            <servlet-name>abploader</servlet-name>
            <servlet-class>de.rpf.customer.ihk.abpboerse.web.servlet.LoaderServlet</servlet-class>
            <load-on-startup>2</load-on-startup>
        </servlet>
    
        <servlet-mapping>
            <servlet-name>action</servlet-name>
            <url-pattern>/abp/action/*</url-pattern>
        </servlet-mapping>
    
        <welcome-file-list>
            <welcome-file>index.jsp</welcome-file>
        </welcome-file-list>
    But I still get a LazyInitializationException when I try to access a lazy collection *after* committing a transaction, but still *within* the request, i.e. before the filter should close the session.

    I changed OpenSessionInViewFilter to have some more logging:
    Code:
    if &#40;isSingleSession&#40;&#41;&#41; &#123;
    			// single session mode
                logger.debug&#40;"Single Session Mode"&#41;;
    			if &#40;TransactionSynchronizationManager.hasResource&#40;sessionFactory&#41;&#41; &#123;
    				// do not modify the Session&#58; just set the participate flag
                    logger.debug&#40;"only participating"&#41;;
    				participate = true;
    			&#125;
    			else &#123;
    				logger.debug&#40;"Opening single Hibernate session in OpenSessionInViewFilter"&#41;;
    				session = getSession&#40;sessionFactory&#41;;
    				TransactionSynchronizationManager.bindResource&#40;sessionFactory, new SessionHolder&#40;session&#41;&#41;;
    			&#125;
    		&#125;
    		else &#123;
                logger.debug&#40;"Deferred Close Mode"&#41;;
    			if &#40;SessionFactoryUtils.isDeferredCloseActive&#40;sessionFactory&#41;&#41; &#123;
    				// do not modify deferred close&#58; just set the participate flag
                    logger.debug&#40;"only participating"&#41;;
    				participate = true;
    			&#125;
    			else &#123;
                    logger.debug&#40;"initDeferredClose"&#41;;
    				SessionFactoryUtils.initDeferredClose&#40;sessionFactory&#41;;
    			&#125;
    		&#125;
    
    		try &#123;
                logger.debug&#40;"going to filterchain"&#41;;
    			filterChain.doFilter&#40;request, response&#41;;
                logger.debug&#40;"back from filterchain"&#41;;
    		&#125;
    
    		finally &#123;
    			if &#40;!participate&#41; &#123;
    				if &#40;isSingleSession&#40;&#41;&#41; &#123;
    					// single session mode
    					TransactionSynchronizationManager.unbindResource&#40;sessionFactory&#41;;
    					logger.debug&#40;"Closing single Hibernate session in OpenSessionInViewFilter"&#41;;
    					closeSession&#40;session, sessionFactory&#41;;
    				&#125;
    				else &#123;
    					// deferred close mode
                        logger.debug&#40;"processing deferred close"&#41;;
    					SessionFactoryUtils.processDeferredClose&#40;sessionFactory&#41;;
    
    				&#125;
    			&#125;
    		&#125;
    And now the log output looks like this:

    Code:
    DEBUG - OpenSessionInViewFilter.lookupSessionFactory&#40;206&#41; | Using session factory 'sessionFactory' for OpenSessionInViewFilter
    DEBUG - OpenSessionInViewFilter.doFilterInternal&#40;161&#41; | Deferred Close Mode
    DEBUG - OpenSessionInViewFilter.doFilterInternal&#40;168&#41; | initDeferredClose
    DEBUG - SessionFactoryUtils.initDeferredClose&#40;494&#41; | Initializing deferred close of Hibernate sessions
    DEBUG - OpenSessionInViewFilter.doFilterInternal&#40;174&#41; | going to filterchain
    DEBUG - AbstractPlatformTransactionManager.getTransaction&#40;195&#41; | Using transaction object &#91;[email protected]cbb&#93;
    DEBUG - AbstractPlatformTransactionManager.getTransaction&#40;267&#41; | Creating new transaction
    DEBUG - SessionFactoryUtils.getSession&#40;324&#41; | Opening Hibernate session
    DEBUG - HibernateTransactionManager.doBegin&#40;368&#41; | Opened new session &#91;net.sf.hibernate.impl.SessionImpl@c68351&#93; for Hibernate transaction
    DEBUG - HibernateTransactionManager.doBegin&#40;410&#41; | Exposing Hibernate transaction as JDBC transaction &#91;org.hsqldb.jdbc.jdbcConnection@d76237&#93;
    DEBUG - AbstractPlatformTransactionManager.triggerBeforeCommit&#40;495&#41; | Triggering beforeCommit synchronization
    DEBUG - AbstractPlatformTransactionManager.triggerBeforeCompletion&#40;510&#41; | Triggering beforeCompletion synchronization
    DEBUG - AbstractPlatformTransactionManager.commit&#40;372&#41; | Initiating transaction commit
    DEBUG - HibernateTransactionManager.doCommit&#40;456&#41; | Committing Hibernate transaction on session &#91;net.sf.hibernate.impl.SessionImpl@c68351&#93;
    DEBUG - AbstractPlatformTransactionManager.triggerAfterCompletion&#40;540&#41; | Triggering afterCompletion synchronization
    DEBUG - HibernateTransactionManager.doCleanupAfterCompletion&#40;532&#41; | Closing Hibernate session &#91;net.sf.hibernate.impl.SessionImpl@c68351&#93; after transaction
    DEBUG - SessionFactoryUtils.doClose&#40;567&#41; | Closing Hibernate session
    ERROR - LazyInitializationException.<init>&#40;25&#41; | Failed to lazily initialize a collection - no session or session was closed
    The HibernateTransactionManager is "Closing Hibernate session after transaction", and not - as I would expect - keeping it open until the request comes out of the filter chain again and letting the filter close the Hibernate session. After committing the transaction, I return from the Struts action I'm in and use a Struts ActionForward (<forward name=...>) to forward (not redirect!) to a JSP. This JSP tries to access the lazy collection, but then the exception mentioned above is thrown.

    I strongly suspect something is wrong with my configuration, but I have no idea what it could be. Any ideas?

    Thanks
    Carl-Eric

  • #2
    how about removing

    <init-param>
    <param-name>singleSession</param-name>
    <param-value>false</param-value>
    </init-param>

    Comment


    • #3
      I tried that, but the result is the same. The log changes only slightly:

      Code:
      DEBUG - OpenSessionInViewFilter.lookupSessionFactory&#40;206&#41; | Using session factory 'sessionFactory' for OpenSessionInViewFilter
      DEBUG - OpenSessionInViewFilter.doFilterInternal&#40;148&#41; | Single Session Mode
      DEBUG - OpenSessionInViewFilter.doFilterInternal&#40;155&#41; | Opening single Hibernate session in OpenSessionInViewFilter
      DEBUG - SessionFactoryUtils.getSession&#40;324&#41; | Opening Hibernate session
      DEBUG - OpenSessionInViewFilter.doFilterInternal&#40;174&#41; | going to filterchain
      DEBUG - AbstractPlatformTransactionManager.getTransaction&#40;195&#41; | Using transaction object &#91;org.springframework.orm.hibernate.HibernateTransactionObj
      ect@1f9c5c8&#93;
      DEBUG - AbstractPlatformTransactionManager.getTransaction&#40;267&#41; | Creating new transaction
      DEBUG - SessionFactoryUtils.getSession&#40;324&#41; | Opening Hibernate session
      DEBUG - HibernateTransactionManager.doBegin&#40;368&#41; | Opened new session &#91;net.sf.hibernate.impl.SessionImpl@12801c5&#93; for Hibernate transaction
      DEBUG - HibernateTransactionManager.doBegin&#40;410&#41; | Exposing Hibernate transaction as JDBC transaction &#91;org.hsqldb.jdbc.jdbcConnection@18c668c&#93;
      DEBUG - AbstractPlatformTransactionManager.triggerBeforeCommit&#40;495&#41; | Triggering beforeCommit synchronization
      DEBUG - AbstractPlatformTransactionManager.triggerBeforeCompletion&#40;510&#41; | Triggering beforeCompletion synchronization
      DEBUG - AbstractPlatformTransactionManager.commit&#40;372&#41; | Initiating transaction commit
      DEBUG - HibernateTransactionManager.doCommit&#40;456&#41; | Committing Hibernate transaction on session &#91;net.sf.hibernate.impl.SessionImpl@12801c5&#93;
      DEBUG - AbstractPlatformTransactionManager.triggerAfterCompletion&#40;540&#41; | Triggering afterCompletion synchronization
      DEBUG - HibernateTransactionManager.doCleanupAfterCompletion&#40;532&#41; | Closing Hibernate session &#91;net.sf.hibernate.impl.SessionImpl@12801c5&#93; after tran
      saction
      DEBUG - SessionFactoryUtils.doClose&#40;567&#41; | Closing Hibernate session
      ERROR - LazyInitializationException.<init>&#40;25&#41; | Failed to lazily initialize a collection - no session or session was closed
      net.sf.hibernate.LazyInitializationException&#58; Failed to lazily initialize a collection - no session or session was closed
      The Hibernate related code that is called in the transaction is this:

      Code:
       public CorporateUser load&#40;int id&#41;
          &#123;
              CorporateUser corp = &#40;CorporateUser&#41; getHibernateTemplate&#40;&#41;.get&#40;CorporateUser.class,
                                                                              new Integer&#40;id&#41;&#41;;
      
              if &#40;corp == null&#41;
              &#123;
                  throw new ObjectRetrievalFailureException&#40;CorporateUser.class,
                                                            new Integer&#40;id&#41;&#41;;
              &#125;
              else
              &#123;
                  return corp;
              &#125;
          &#125;
      
          public CorporateUser loadOrCreate&#40;int id&#41;
          &#123;
              CorporateUser corp = null;
      
              try
              &#123;
                  corp = load&#40;id&#41;;
              &#125;
              catch &#40;ObjectRetrievalFailureException e&#41;
              &#123;
                  if &#40;corp == null&#41;
                  &#123;
                      corp = new CorporateUser&#40;&#41;;
                      corp.setId&#40;id&#41;;
                      save&#40;corp&#41;;
                  &#125;
              &#125;
      
              return corp;
          &#125;
      
          public CorporateUser save&#40;CorporateUser c&#41;
          &#123;
              getHibernateTemplate&#40;&#41;.saveOrUpdate&#40;c&#41;;
      
              return c;
          &#125;
      Only the method loadOrCreate() is called from the Struts Action. In the JSP this request ultimately gets to a lazy collection contained in the CorporateUser object is opened, which causes the error. The transaction definitions are:

      Code:
      <bean id="txProxyTemplate" lazy-init="true"
              class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
              >
              <property name="transactionManager"><ref local="transactionManager"/></property>
              <property name="transactionAttributes">
                  <props>
                      <prop key="loadOrCreate">PROPAGATION_REQUIRED</prop>
                      <prop key="load*">PROPAGATION_SUPPORTS,readOnly,+Throwable</prop>
                      <prop key="get*">PROPAGATION_SUPPORTS,readOnly</prop>
                      <prop key="find*">PROPAGATION_SUPPORTS,readOnly</prop>
                      <prop key="save*">PROPAGATION_REQUIRED</prop>
                      <prop key="create*">PROPAGATION_REQUIRED</prop>
                      <prop key="delete*">PROPAGATION_REQUIRED</prop>
                  </props>
              </property>
          </bean>
      I suspect I haven't quite understood some fine point in all this, but so far I have no idea.

      Thanks
      Carl-Eric

      Comment


      • #4
        SessionFactoryUtils giving me 2 instances of SessionFactory?

        I tried stepping through a whole request in Tomcat 4 with Eclipse 3 now, and I found out the following:

        In OpenSessionInViewFilter initDeferredClose() is called and the deferred close holder set is also created and stored in the appropriate ThreadLocal.

        When the request gets to my Struts Action and calls the DAO method, weird things happen. I do the DAO call as usual via getHibernateTemplate().load(...). When I continue in the debugger into HibernateTemplate, the getSessionFactory() method returns a valid SessionFactory, but its "id" as displayed in the Eclipse debugger is *not* the same as the one I saw for the SessionFactory that was stored in the deferred close holder. I'm not too familiar with the debugger, but I think this means that this is a different instance. Where does it come from?

        The problem with this becomes obvious in closeSessionOrRegisterDeferredClose(). The SessionFactory that is passed as an argument here is again this second instance that was also in the HibernateTemplate. The deferred close map contains the *first* instance, so the contains() check returns false and the method believes this session is not registered to be closed later. It closes the session, and then of course I get the LazyInitializationException later on.

        So my problem now is: Where does this second SessionFactory come from, and what can I do about it?

        Thanks
        Carl-Eric

        Comment


        • #5
          More debugging: It seems that the OpenSessionInViewFilter is getting a different SessionFactory instance than the one that is assigned to the HibernateDaoSupport instances which form my DAO layer. How can this be?

          Thanks
          Carl-Eric

          Comment


          • #6
            Originally posted by calle
            More debugging: It seems that the OpenSessionInViewFilter is getting a different SessionFactory instance than the one that is assigned to the HibernateDaoSupport instances which form my DAO layer. How can this be?
            If your configuration (web.xml, applicationContext.xml, ...) are corrects, this should not happen.

            from OpenSessionInViewFilter source:
            Code:
            	protected SessionFactory lookupSessionFactory&#40;&#41; &#123;
            		if &#40;logger.isDebugEnabled&#40;&#41;&#41; &#123;
            			logger.debug&#40;"Using session factory '" + getSessionFactoryBeanName&#40;&#41; + "' for OpenSessionInViewFilter"&#41;;
            		&#125;
            		WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext&#40;getServletContext&#40;&#41;&#41;;
            		return &#40;SessionFactory&#41; wac.getBean&#40;getSessionFactoryBeanName&#40;&#41;&#41;;
            	&#125;
            As you can see, OpenSessionInViewFilter looks for a sessionFactory in the ApplicationContext, and since sessionFactory is generally singleton, OpenSessionInViewFilter should use the same sessionFactory as your DAOs.

            I do not know how sitemesh manages page composition, but could you try to inverse the order of your filters and put hibernate first:
            Code:
                <filter-mapping> 
                    <filter-name>hibernate</filter-name> 
                    <url-pattern>/abp/action/*</url-pattern> 
                    <dispatcher>REQUEST</dispatcher> 
                    <dispatcher>FORWARD</dispatcher> 
                </filter-mapping> 
                <filter-mapping> 
                    <filter-name>sitemesh</filter-name> 
                    <url-pattern>/abp/action/*</url-pattern> 
                    <dispatcher>REQUEST</dispatcher> 
                    <dispatcher>FORWARD</dispatcher> 
                    <dispatcher>ERROR</dispatcher> 
                </filter-mapping>
            HTH

            Comment


            • #7
              I temporarily disabled SiteMesh completely for other reasons today. It did not change the OpenSessionInViewFilter behavior. I am currently out of ideas, but I'll post my config files - maybe you can see what is wrong.

              web.xml:
              Code:
              <?xml version="1.0" encoding="UTF-8"?>
              <!DOCTYPE web-app PUBLIC
                  "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
                  "http&#58;//java.sun.com/dtd/web-app_2_3.dtd"
              >
              <web-app>
                  <display-name>Ausbildungsplatzboerse</display-name>
                  <filter>
                      <filter-name>sitemesh</filter-name>
                      <filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class>
                  </filter>
                  <filter>
                      <filter-name>hibernate</filter-name>
                      <filter-class>org.springframework.orm.hibernate.support.OpenSessionInViewFilter</filter-class>
                      <!--init-param>
                          <param-name>singleSession</param-name>
                          <param-value>false</param-value>
                      </init-param-->
                  </filter>
              
                  <!--filter-mapping>
                      <filter-name>sitemesh</filter-name>
                      <url-pattern>/abp/action/*</url-pattern>
                  </filter-mapping-->
                  <filter-mapping>
                      <filter-name>hibernate</filter-name>
                      <url-pattern>/abp/action/*</url-pattern>
                  </filter-mapping>
              
                  <listener>
                      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
                  </listener>
              
                  <servlet>
                      <servlet-name>action</servlet-name>
                      <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
                      <load-on-startup>1</load-on-startup>
                  </servlet>
                  <servlet>
                      <servlet-name>abploader</servlet-name>
                      <servlet-class>myproject.web.servlet.LoaderServlet</servlet-class>
                      <load-on-startup>2</load-on-startup>
                  </servlet>
              
                  <servlet-mapping>
                      <servlet-name>action</servlet-name>
                      <url-pattern>/abp/action/*</url-pattern>
                  </servlet-mapping>
              
                  <welcome-file-list>
                      <welcome-file>index.jsp</welcome-file>
                  </welcome-file-list>
              
                  <taglib>
                      <taglib-uri>/tags/struts-bean</taglib-uri>
                      <taglib-location>/WEB-INF/lib/struts-bean-el.tld</taglib-location>
                  </taglib>
                  <taglib>
                      <taglib-uri>/tags/struts-html</taglib-uri>
                      <taglib-location>/WEB-INF/lib/struts-html-el.tld</taglib-location>
                  </taglib>
                  <taglib>
                      <taglib-uri>/tags/core</taglib-uri>
                      <taglib-location>/WEB-INF/lib/c-1_0.tld</taglib-location>
                  </taglib>
                  <taglib>
                      <taglib-uri>/tags/display</taglib-uri>
                      <taglib-location>/WEB-INF/lib/displaytag-el-12.tld</taglib-location>
                  </taglib>
              </web-app>
              struts-config.xml:


              Code:
              <?xml version="1.0" encoding="UTF-8"?>
              <!DOCTYPE struts-config PUBLIC
                  "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
                  "http&#58;//struts.apache.org/dtds/struts-config_1_2.dtd">
              <struts-config>
              
                  <!-- ======================================== Form Bean Definitions -->
              
                  <form-beans>
                      <form-bean name="jobOfferForm"
                                 type="myproject.struts.form.JobOfferForm"/>
                  </form-beans>
              
                  <!-- =================================== Global Forward Definitions -->
              
                  <global-forwards>
                      <forward name="corpaccessdenied" path="/WEB-INF/pages/welcome.jsp"/>
                  </global-forwards>
              
                  <!-- =================================== Action Mapping Definitions -->
              
                  <action-mappings>
                      <action path="/welcome"
                              forward="/WEB-INF/pages/welcome.jsp" />
                      <action path="/corpOverview"
                              type="org.springframework.web.struts.DelegatingActionProxy">
                          <forward name="success" path="/WEB-INF/pages/corp/overview.jsp"/>
                      </action>
                      <action path="/createOffer"
                              name="jobOfferForm"
                              scope="request"
                              type="org.springframework.web.struts.DelegatingActionProxy">
                          <forward name="success" path="/WEB-INF/pages/corp/createoffer.jsp"/>
                      </action>
                      <action path="/submitOffer"
                              name="jobOfferForm"
                              scope="request"
                              type="org.springframework.web.struts.DelegatingActionProxy">
                          <forward name="success" path="/WEB-INF/pages/corp/editoffer.jsp"/>
                      </action>
                      <action path="/saveOffer"
                              type="org.springframework.web.struts.DelegatingActionProxy">
                      </action>
                      <action path="/requestActivation"
                              type="org.springframework.web.struts.DelegatingActionProxy">
                      </action>
                  </action-mappings>
              
              
                  <!-- ================================ Message Resources Definitions -->
              
                  <message-resources parameter="application"/>
                  <message-resources parameter="job" key="jobResources"/>
                  <message-resources parameter="region" key="regionResources"/>
                  <message-resources parameter="jobcategory" key="jobcatResources"/>
              
                  <!-- ======================================= Plug Ins Configuration -->
                  <plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
                      <set-property property="contextConfigLocation"
                                    value="/WEB-INF/applicationContext.xml, /WEB-INF/action-servlet.xml"/>
                  </plug-in>
              </struts-config>
              applicationContext.xml

              Code:
              <?xml version="1.0" encoding="UTF-8"?>
              <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
                  "http&#58;//www.springframework.org/dtd/spring-beans.dtd">
              
              <beans>
                  <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
                      <property name="driverClassName"><value>org.hsqldb.jdbcDriver</value></property>
                      <!--property name="url"><value>jdbc&#58;hsqldb&#58;db/abp</value></property-->
                      <property name="url"><value>jdbc&#58;hsqldb&#58;mem&#58;abp</value></property>
                      <property name="username"><value>sa</value></property>
                      <property name="password"><value></value></property>
                  </bean>
              
                  <!-- Hibernate SessionFactory -->
                  <bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
                      <property name="dataSource"><ref local="dataSource"/></property>
                      <property name="mappingResources">
                          <list>
                              <value>de/rpf/customer/ihk/abpboerse/core/CorporateUser.hbm.xml</value>
                              <value>de/rpf/customer/ihk/abpboerse/core/TraineeUser.hbm.xml</value>
                              <value>de/rpf/customer/ihk/abpboerse/core/JobOffer.hbm.xml</value>
                          </list>
                      </property>
                      <property name="hibernateProperties">
                      <props>
                          <prop key="hibernate.dialect">net.sf.hibernate.dialect.HSQLDialect</prop>
                          <prop key="hibernate.hbm2ddl.auto">create</prop>
                          <prop key="hibernate.show_sql">false</prop>
                      </props>
                      </property>
                  </bean>
              
                  <!-- Transaction manager for a single Hibernate SessionFactory &#40;alternative to JTA&#41; -->
                  <bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
                      <property name="sessionFactory"><ref local="sessionFactory"/></property>
                  </bean>
                  <bean id="txProxyTemplate" lazy-init="true"
                      class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
                      >
                      <property name="transactionManager"><ref local="transactionManager"/></property>
                      <property name="transactionAttributes">
                          <props>
                              <prop key="loadOrCreate">PROPAGATION_REQUIRED</prop>
                              <prop key="load*">PROPAGATION_SUPPORTS,readOnly,+Throwable</prop>
                              <prop key="get*">PROPAGATION_SUPPORTS,readOnly</prop>
                              <prop key="find*">PROPAGATION_SUPPORTS,readOnly</prop>
                              <prop key="save*">PROPAGATION_REQUIRED</prop>
                              <prop key="create*">PROPAGATION_REQUIRED</prop>
                              <prop key="delete*">PROPAGATION_REQUIRED</prop>
                          </props>
                      </property>
                  </bean>
                  
                  <!-- Add DAOs here -->
                  <bean id="corpUserDAO" parent="txProxyTemplate">
                      <property name="target">
                          <bean class="myproject.dao.hibernate.CorpUserDAOImpl">
                              <property name="sessionFactory">
                                  <ref bean="sessionFactory"/>
                              </property>
                          </bean>
                      </property>
                  </bean>
                  <bean id="traineeUserDAO" parent="txProxyTemplate">
                      <property name="target">
                          <bean class="myproject.dao.hibernate.TraineeUserDAOImpl">
                              <property name="sessionFactory">
                                  <ref bean="sessionFactory"/>
                              </property>
                          </bean>
                      </property>
                  </bean>
                  <bean id="jobDAO" parent="txProxyTemplate">
                      <property name="target">
                          <bean class="myproject.dao.hibernate.JobDAOImpl">
                              <property name="sessionFactory">
                                  <ref bean="sessionFactory"/>
                              </property>
                          </bean>
                      </property>
                  </bean>
                  
                  <!-- Add Managers here -->
                  <bean id="authUtils" class="myproject.web.util.AuthorizationUtils">
                      <property name="corpUserDAO"><ref bean="corpUserDAO"/></property>
                  </bean>
              </beans>
              action-servlet.xml:

              Code:
              <?xml version="1.0" encoding="UTF-8"?>
              <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
                  "http&#58;//www.springframework.org/dtd/spring-beans.dtd">
              <beans>
                  <bean name="corpActionTemplate" 
                        class="myproject.struts.action.CorpAction"
                        lazy-init="true">
                      <property name="authUtils">
                          <ref bean="authUtils"/>
                      </property>
                      <property name="authUtils">
                          <ref bean="authUtils"/>
                      </property>
                  </bean>
                  <bean name="/corpOverview"
                        class="myproject.struts.action.CorpOverviewAction"
                        parent="corpActionTemplate">
                      <property name="corpUserDAO">
                          <ref bean="corpUserDAO"/>
                      </property>
                  </bean>
                  <bean name="/createOffer"
                        class="myproject.struts.action.CreateOfferAction"
                        parent="corpActionTemplate">
                  </bean>
                  <bean name="/submitOffer"
                        class="myproject.struts.action.SubmitOfferAction"
                        parent="corpActionTemplate">
                  </bean>
              </beans>
              If there is anything else I can do to explain or find a solution, please tell me - I'm out of ideas right now (though that might be because it's the middle of Friday night already ;-) )

              Thanks!
              Carl-Eric

              Comment


              • #8
                (though that might be because it's the middle of Friday night already )
                It is 20:43 in Québec City

                Ok, I can see the following "issues":
                1. struts-config.xml:
                <plug-in className="org.springframework.web.struts.ContextL oaderPlugIn">
                <set-property property="contextConfigLocation"
                value="/WEB-INF/applicationContext.xml, /WEB-INF/action-servlet.xml"/>
                </plug-in>
                ContextLoaderPlugIn loads a configuration file, creates a new webcontext and connect it (child-parent) to the root web application context (the one created by org.springframework.web.context.ContextLoaderListe ner)
                I can see that you provided WEB-INF/applicationContext.xml to ContextLoaderPlugIn, this will result in all beans defined in this file configured twice, in the root wac and in the wac created by Struts Plugin... Result: You will be using two sessionFactories!!!
                The configuration should be:
                Code:
                    <plug-in className="org.springframework.web.struts.ContextLoaderPlugIn"> 
                        <set-property property="contextConfigLocation" 
                                      value="/WEB-INF/action-servlet.xml"/> 
                    </plug-in>
                2. transaction demarcation: (not really an issue)
                <!-- Add DAOs here -->
                <bean id="corpUserDAO" parent="txProxyTemplate">
                <property name="target">
                <bean class="myproject.dao.hibernate.CorpUserDAOImpl">
                <property name="sessionFactory">
                <ref bean="sessionFactory"/>
                </property>
                </bean>
                </property>
                </bean>
                <!-- Add Managers here -->
                <bean id="authUtils" class="myproject.web.util.AuthorizationUtils">
                <property name="corpUserDAO"><ref bean="corpUserDAO"/></property>
                </bean>
                Generally, it is a good idea to apply transaction management in the service / manager layer
                3. datasource configuration: (not really an issue)
                <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverM anagerDataSource">
                <property name="driverClassName"><value>org.hsqldb.jdbcDrive r</value></property>
                <!--property name="url"><value>jdbc:hsqldb:db/abp</value></property-->
                <property name="url"><value>jdbc:hsqldb:mem:abp</value></property>
                <property name="username"><value>sa</value></property>
                <property name="password"><value></value></property>
                </bean>
                DriverManagerDataSource is very usefull for development / testing, for production mode, consider the use of a true pooling datasource manager.

                HTH

                Comment


                • #9
                  It was the duplicate context in struts-config.xml. I removed it and now it works as expected. Yay!

                  I will fix both the transaction and the data source configuration later, I'm still rather early in the development and the current setup is only supposed to verify that it all works.

                  Thanks a lot for your help!
                  Carl-Eric

                  Comment


                  • #10
                    Look at this maybe simpler to configure.

                    http://forum.springframework.org/showthread.php?t=10519
                    Last edited by robyn; May 14th, 2006, 10:59 AM.

                    Comment

                    Working...
                    X