Announcement Announcement Module
Collapse
No announcement yet.
Connection leak on lazy load Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • #16
    Earlier we had hibernate properties to specify the connection pooling configurations using c3p0, however, we thought that is redundant because we already have pooling (connection pool) in the application server and therefore removed now

    The Dao classes extend HibernateDaoSupport class, the class has a setSessionFactory to inject the session factory created. example configuration below:
    Code:
    	<bean id="testDao"
    		class="com.test.dao.impl.TestDaoHibernate">
    		<property name="sessionFactory" ref="ehealthCmsSessionFactory" />
    	</bean>

    Comment


    • #17
      I'm more interested in the internals of that class.

      The hibernate.properties can be indeed redundant at least the c3p0 properties you mention because you are using a JNDI datasource. However you aren't using that anymore (removed as you say) so it isn't something that can cause issues.

      Comment


      • #18
        The Dao classes contain methods to retrieve data using HQL. Below is an example:

        Code:
        		Query query = getSession().createQuery(sql.toString());
        		query = query.setString("siteKey", siteKey.toString());
        		query = query.setParameterList("userTypes", userTypes);
        		if (itemName != null)
        			query = query.setString("itemName", itemName);
        		if (product != null)
        			query = query.setString("product", product);
        
        		contents = query.list();
        I am wondering why the connection leaks are happening only on lazy loads.

        Comment


        • #19
          Still not what I want to see . What does the getSession method do?

          If it is the one from the HibernateDaoSupport (which isn't recommended to use anymore!!) you also need to call releaseSession else the session remains open until it times out (i.e. leaking connections).

          Either use a HibernateCallback to execute the code in the HibernateTemplate or use the getSessionFactory().getCurrentSession(). The latter is recommended.

          Comment


          • #20
            Yes, the getSession() that I referred is indeed from the HibernateDaoSupport class.

            In the article you posted it is quoted that
            Since Hibernate 3.0.1 (and in the Java Persistence API from the moment it was first released) it became possible for Spring to manage the underlying resource without you having to go through any of the templates that are available for those technologies. This means that even if you are using the Hibernate API directly (for example through SessionFactory.getCurrentSession()), you will still be using a Spring-managed Hibernate Sessio
            Does the above quote does not apply to getSession of HibernateDaoSupport? If we were to do "releaseSession" specifically then what does the OSIVI do.
            I happened to take the detailed logger of OSIVI and it appears that it (the OSIVI) indeed closes the session, below is an excerpt of the logs:

            Code:
            01 Sep 2009 16:48:28,413 DEBUG [null] OpenSessionInViewInterceptor - Opening single Hibernate Session in OpenSessionInViewInterceptor
            01 Sep 2009 16:48:28,413 DEBUG [null] SessionFactoryUtils - Opening Hibernate Session
            01 Sep 2009 16:48:28,423 ERROR [null] TestController - Executing testManager method
            01 Sep 2009 16:48:34,772 DEBUG [null] OpenSessionInViewInterceptor - Closing single Hibernate Session in OpenSessionInViewInterceptor
            01 Sep 2009 16:48:34,772 DEBUG [null] SessionFactoryUtils - Closing Hibernate Session
            Are there any specific reasons you want to suggest getCurrentSession() of sessionFactory?

            BTW The application is already running in production and changing all getSession() to something else is a tedious task both from development and testing point of views.

            Can you also throw some light why the connection leak should happen on lazy load? Do you think its a mere co-incidence that its happening on lazy loads? I never saw connection leak when the data is accessed non-lazy way.

            Thanks for your patience.

            Comment


            • #21
              Does the above quote does not apply to getSession of HibernateDaoSupport?
              No it doesn't.

              If we were to do "releaseSession" specifically then what does the OSIVI do.
              I happened to take the detailed logger of OSIVI and it appears that it (the OSIVI) indeed closes the session, below is an excerpt of the logs:
              The ISOVI doesn't know about the session opened with getSession so that remains open, when a request comes in it opens a session, and closes it when the request has finished. However the getSession opens a new one.

              Can you also throw some light why the connection leak should happen on lazy load? Do you think its a mere co-incidence that its happening on lazy loads? I never saw connection leak when the data is accessed non-lazy way.
              I suspect it is a co-incidence due to the getSession.

              The rule of thumb if you use getSession manage/release the session yourself.

              Are there any specific reasons you want to suggest getCurrentSession() of sessionFactory?
              Because that will return the single session opened by the OSIVI.

              BTW The application is already running in production and changing all getSession() to something else is a tedious task both from development and testing point of views.
              If you want a stable application that should/is the way to go. You can leave the getSession() in place simply replace the extension of HibernateDaoSupport by your own class which also has a getSession().

              Code:
              public abstract class AbstractHibernateDao {
              
                protected SessionFactory sessionFactory;
              
                public void setSessionFactory(SessionFactory sessionFactory) {
                  this.sessionFactory=sessionFactory;
                }
              
                protected final Session getSession() {
                  return sessionFactory.getCurrentSession();
                }
              
                ..Other shared methods.
              
              }
              Then you could quite easily do a search and replace...
              Last edited by Marten Deinum; Sep 15th, 2009, 07:24 AM.

              Comment


              • #22
                Sorry I am confused, can you elaborate why the session opened by getSession() will not be closed by OSIVI? The logger above are stating that the session is getting closed?

                Here is what my understanding, please correct me if this is wrong:
                • When a request is initiated, OSIVI creates a connection (session)
                • During the execution, the control reaches the Dao layer and eventually executes HibernateDaoSupport.getSession(). So at this time, the session that was opened by OSIVI (at step 1) will be used?
                • Upon executing the query, eventually, the control comes back to the controller and request finishes, this will trigger OSIVI to close the session

                Can you also elaborate the life cycle of the session (connection) getSession() case vs. getSessionFactory().getSession()?

                Thanks,
                Ram

                Comment


                • #23
                  During the execution, the control reaches the Dao layer and eventually executes HibernateDaoSupport.getSession(). So at this time, the session that was opened by OSIVI (at step 1) will be used?
                  No that will not be used.

                  getSession will eventually call sessionFactory.openSession which creates a new hibernate session OUTSIDE the control of spring and thus OUTSIDE the control of the OSIVI.

                  sessionFactory.getCurrentSession taps into the hibernate session management (contextual sessions) and returns the single session opened by the OSIVI.

                  You can check what happens simply enable debug logging for org.springframework.transaction.support and org.springframework.orm.hibernate3.support and check the debug logging.

                  Comment


                  • #24
                    In order to understand what happens in a request flow, I captured the below log
                    Code:
                    15 Sep 2009 21:01:35,310 DEBUG AbstractUrlHandlerMapping - Looking up handler for [/test.do]
                    15 Sep 2009 21:01:35,310 DEBUG DispatcherServlet - Testing handler adapter [[email protected]367]
                    15 Sep 2009 21:01:35,310 DEBUG DispatcherServlet - Testing handler adapter [org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter@3d3258]
                    15 Sep 2009 21:01:35,310 DEBUG DispatcherServlet - Last-Modified value for [/hptestsite/test.do] is: -1
                    15 Sep 2009 21:01:35,310 DEBUG DispatcherServlet - DispatcherServlet with name 'spring' received request for [/hptestsite/test.do]
                    15 Sep 2009 21:01:35,310 DEBUG DispatcherServlet - Bound request context to thread: org.acegisecurity.wrapper.SavedRequestAwareWrapper@1b46c0d
                    15 Sep 2009 21:01:35,310 DEBUG OpenSessionInViewInterceptor - Opening single Hibernate Session in OpenSessionInViewInterceptor
                    15 Sep 2009 21:01:35,340 DEBUG DispatcherServlet - Testing handler adapter [[email protected]367]
                    15 Sep 2009 21:01:35,340 DEBUG DispatcherServlet - Testing handler adapter [org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter@3d3258]
                    15 Sep 2009 21:01:35,340 ERROR TestController - Executing testManager method
                    15 Sep 2009 21:01:35,340 DEBUG HibernateTransactionManager - Found thread-bound Session [org.hibernate.impl.SessionImpl@d95b06] for Hibernate transaction
                    15 Sep 2009 21:01:35,350 DEBUG AbstractPlatformTransactionManager - Using transaction object [org.springframework.orm.hibernate3.HibernateTransactionManager$HibernateTransactionObject@1e6e860]
                    15 Sep 2009 21:01:35,350 DEBUG TransactionAspectSupport - Getting transaction for [com.jnj.hp2.hptestsite.service.TestManager.test]
                    15 Sep 2009 21:01:36,502 DEBUG TransactionAspectSupport - Completing transaction for [com.jnj.hp2.hptestsite.service.TestManager.test]
                    15 Sep 2009 21:01:36,502 DEBUG AbstractPlatformTransactionManager - Triggering beforeCommit synchronization
                    15 Sep 2009 21:01:36,502 DEBUG AbstractPlatformTransactionManager - Triggering beforeCompletion synchronization
                    15 Sep 2009 21:01:36,502 DEBUG AbstractPlatformTransactionManager - Triggering afterCommit synchronization
                    15 Sep 2009 21:01:36,512 DEBUG AbstractPlatformTransactionManager - Triggering afterCompletion synchronization
                    15 Sep 2009 21:01:36,512 ERROR TestController - waiting....
                    15 Sep 2009 21:01:36,822 ERROR TestController - setting pageAttributes------------------------------
                    15 Sep 2009 21:01:37,143 ERROR TestController - item.getKeywords() = 5
                    15 Sep 2009 21:01:37,143 ERROR TestController - missie,innovatie,kwalitatieve farmaceutische producten,diensten,patiŽnten
                    15 Sep 2009 21:01:37,143 ERROR TestController - setting pageAttributes completed-------------------
                    15 Sep 2009 21:01:37,143 ERROR TestController - Leaving handleRequestInternal
                    15 Sep 2009 21:01:37,153 DEBUG OpenSessionInViewInterceptor - Flushing single Hibernate Session in OpenSessionInViewInterceptor
                    15 Sep 2009 21:01:37,153 DEBUG AbstractCachingViewResolver - Cached view [test]
                    15 Sep 2009 21:01:37,153 DEBUG DispatcherServlet - Rendering view [org.springframework.web.servlet.view.JstlView: name 'test'; URL [/pages/test.jsp]] in DispatcherServlet with name 'spring'
                    15 Sep 2009 21:01:37,153 DEBUG AbstractView - Rendering view with name 'test' with model {item=bf19514831e99d5bf10c12b5eea91bef - /backgrounders/janssen-cilag.be_dut/pool_content/about_mission.xml - about_mission} and static attributes {}
                    15 Sep 2009 21:01:37,163 DEBUG AbstractView - Added model object 'item' of type [com.jnj.hp2.ehealth.cms.model.Backgrounder] to request in view with name 'test'
                    15 Sep 2009 21:01:37,163 DEBUG AbstractView - Added model object 'rc' of type [org.springframework.web.servlet.support.RequestContext] to request in view with name 'test'
                    15 Sep 2009 21:01:37,163 DEBUG InternalResourceView - Forwarding to resource [/pages/test.jsp] in InternalResourceView 'test'
                    15 Sep 2009 21:01:38,415 DEBUG OpenSessionInViewInterceptor - Closing single Hibernate Session in OpenSessionInViewInterceptor
                    15 Sep 2009 21:01:38,415 DEBUG DispatcherServlet - Cleared thread-bound request context: org.acegisecurity.wrapper.SavedRequestAwareWrapper@1b46c0d
                    15 Sep 2009 21:01:38,415 DEBUG FrameworkServlet - Successfully completed request
                    The session life cycle begins and ends at OSIVI. I am still not sure what is flow (from a session perspective) when we access data that is lazily loaded.

                    In the above log,
                    15 Sep 2009 21:01:37,143 ERROR TestController - item.getKeywords() = 5
                    15 Sep 2009 21:01:37,143 ERROR TestController - missie,innovatie,kwalitatieve farmaceutische producten,diensten,patiŽnten
                    the item.getKeywords() is lazily loaded, i don't see any logger statements that indicates which session is getting used, can you throw some light on what happens (I mean session life cycle) when we try to access lazy data?

                    Comment


                    • #25
                      15 Sep 2009 21:01:37,143 ERROR TestController - missie,innovatie,kwalitatieve farmaceutische producten,diensten,patiŽnten
                      So we could have done this in dutch judging from the log messages .

                      the item.getKeywords() is lazily loaded, i don't see any logger statements that indicates which session is getting used, can you throw some light on what happens (I mean session life cycle) when we try to access lazy data?
                      Well you think you are using your own objects but you aren't, you are using your objects which are modified (proxied) by hibernate, that proxy is handling all the lazy loading. Each hibernate object has an internal reference to the session that was used to retrieve that specific object.

                      Although this flow doesn't show the creation of new sessions I still urge you to switch to the getCurrentSession on the sessionfactory for a more reliable piece of software (and because it is the recommended approach).

                      How easy is it to replay the exception. I suggest replaying it with debug logging turned on to see where it goes haywire. I suspect some rogue sessions (and thus connections).

                      Comment


                      • #26
                        The data is from the database (which is in dutch).

                        Thanks for all your patience and help so far, well the base DAO class is in our framework and I need to have a strong case which proves that getSession() opens sessions that are not closed ;-) hence I am trying to generate as much verbose log as possible just to see that a session got opened and that did not get closed.

                        I can use the logs and can push for sessionFactory.getCurrentSession() change to the base class.

                        Comment


                        • #27
                          When you said
                          Each hibernate object has an internal reference to the session that was used to retrieve that specific object.
                          I just wanted to let you know that we cache the output of manager methods (list of objects retrieved by hibernate), do you think caching can contribute to connection leaks?

                          Comment


                          • #28
                            I just wanted to let you know that we cache the output of manager methods (list of objects retrieved by hibernate), do you think caching can contribute to connection leaks?
                            That can very well be, session remains attached to objects, keeps connection open (maybe not closable due to caching). So that could be a possibility. Instead of caching the output of the manager methods you want to investigate 2nd level cache of hibernate.

                            Comment


                            • #29
                              I have an issue ecactly like this!
                              What was the final verdict on this?? Reading this three pages of threads were like reading an Agatha Cristie novel..only to realize that the final chapter did not reveal who the real killer was lol!
                              Ram , how did you end up going about fixing this issue?

                              Comment

                              Working...
                              X