Announcement Announcement Module
Collapse
No announcement yet.
Large No of Session Leaks in Spring + Hibernate Application Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Large No of Session Leaks in Spring + Hibernate Application

    Hi all,
    I have recently started working on a legacy application that uses Hibernate and spring. Since it is a legacy one, in the code we are using HibernateDAOSupport for using Hibernate in Spring. Now every few days our DB chocks, I investigated and found that it is due to large number of open sessions . Originally this is done

    1. All DAO's in the application extends HibernateDAOSupport.

    2. For Transaction configuration, an annotation-based approach is used with @Transactional annotation on top of every service class.And below is specified in spring xml file for enabling the same.
    <!-- enable the configuration of transactional behavior based on annotations -->
    <tx:annotation-driven transaction-manager="transactionManager" order="10000" />

    3. Below is a simple method in one of the DAO's

    Code:
    @SuppressWarnings("unchecked")
    	public CartDetails getCartDetailsByCartId(Long cartId) {
    
    		Criteria criteria = getSession().createCriteria(CartDetails.class);
    		criteria.add(Restrictions.eq("cartId", cartId));
    		List<CartDetails> cartDetailsList = (List<CartDetails>)criteria.list();
    		if (cartDetailsList != null && cartDetailsList.size() > 0) {
    			return (CartDetails) cartDetailsList.get(0);
    		} else {
    			return null;
    		}
    	}
    
    }
    As you can see in all the DAO's this is used getSession().createCriteria(CartDetails.class); .getSession() method of HibernateDAOSupport class is called and as per my understanding this is the issue of large number of open sessions. Please let me know if my understanding is correct.

    So to fix this I modified the DAO as below (Used HibernateTemplateMethod)

    Code:
    @SuppressWarnings("unchecked")
    	public CartDetails getCartDetailsByCartId(Long cartId) {
    		log.error("Inside CartDetailsDaoHibernate:getCartDetailsByCartId");
    		Session session=getHibernateTemplate().getSessionFactory().getCurrentSession();	
    
    		Criteria criteria = session.createCriteria(CartDetails.class);
    		criteria.add(Restrictions.eq("cartId", cartId));
    		List<CartDetails> cartDetailsList = (List<CartDetails>)criteria.list();
    		if (cartDetailsList != null && cartDetailsList.size() > 0) {
    			return (CartDetails) cartDetailsList.get(0);
    		} else {
    			return null;
    		}
    	}
    Please let me know if this approach is correct? As per my understanding getCurrentSession() returns the session and closes it automatically once done.Please let me know if my above understanding is correct. I know using HibernateDAOSupport is deprecated but I can't do much in this scenario.

  • #2
    That should solve your issue as it will return the transaction bound session instead of creating a new one (with getSession).

    Another solution would/could be to use DetachedCriteria instead of Criteria and use the HibernateTemplate to execute those (but that would be a far greater refactoring then this one).

    Comment


    • #3
      Hi Marten,
      Thanks for your reply . Can you please confirm this "I do not need to explicitly close the sessions if I use below approach right?
      Code:
       Session session=getHibernateTemplate().getSessionFactory().getCurrentSession();
      It is Spring that will manage the sessions right? And also is there any limit on the number of sessions that we can open using hibernate+spring in our application.

      Comment


      • #4
        SPrings transactionmanagement will close the session as soon as the transaction ends, so don't close sessions yourself.

        The number of sessions you can open is basically unlimited (from a spring or hibernate perspective), in general it is limited on how many connections the database allows (and memory consumption).

        Comment


        • #5
          Hi Marten,
          Thanks for all the useful information that you shared. I was wondering apart from this we are using DBCP in Spring for connection pooling and below are the values that are currently configured

          HTML Code:
          datasource.maxActive = 100
          datasource.maxIdle = 30
          datasource.maxWait = 1000
          datasource.defaultAutoCommit = true
          datasource.removeAbandoned = true
          datasource.removeAbandonedTimeout = 60
          datasource.poolPreparedStatements = true
          datasource.maxOpenPreparedStatements = 1000
          In our application we query the database say around 400-500 queries per second using hibernate and spring.And as per my understanding the current value of maxActive=100 seems to be a bottleneck for this.Please let me know if my understanding is correct and if I must change the other values for this connection pool.

          Comment


          • #6
            maxActive is the number of concurrent connections it doesn't say anything about number of queries.

            There is no general way to tell if this is sufficient of not, the only way to know is to measure/loadtest your application.

            Comment

            Working...
            X