Announcement Announcement Module
Collapse
No announcement yet.
HibernateDaoSupport's relaseSession() don't release connections to c3p0 pool Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • HibernateDaoSupport's relaseSession() don't release connections to c3p0 pool

    Hello members, I'm using spring + hibernate with c3p0 for connection pooling and my application is having a connection leaking in the pool.

    My DAOs extends HibernateDaoSupport, when I use the HibernateTemplate's methods (i.e. find()) after doing the queries the connections are correctly released to the connection pool.

    But if I get a session with HibernateDaoSupport's getSession(), use it directly and then call the releaseSession() method, the connections are not released to the pool.

    Do anyone know how can I make the releaseSession() method (or any other way) to return the underlying session's connection to the connection pool?




    Thanks in advance

    PS: I want to use the session directly because I'm trying to make my code not too dependent on spring.




    Here is a sample of how I'm using the getSession() method in a DAO that extends HibernateDaoSupport:

    Code:
    public UserDto getUser(String username) {
    	Session session = null;
    	UserDto user = null;
    
    try {
    	session = getSession();
    	Query query = session.createQuery("from UserDto where username=:username");
    	query.setParameter("username", username);
    			
    	List<UserDto> users = (List<UserDto>) query.list();
    	if(users.size() == 1) {
    		user = users.get(0);
    		}
    	}
    finally {
    	releaseSession(session);
    	}
    return user;
    }

  • #2
    1) Don't use getSession
    2) Don't use the HibernateDaoSupport


    I suggest a read of this blog post by alef. Simply use the SessionFactory directly and let the Springs transaction management take care of the rest.

    releaseSession indeed doesn't release the connection because that is part of springs transaction management (releasing the session doesn't mean that your transaction is over!). Next to that you indicate that you don't want to depend to much on spring but still your complete class hierarchy depends on it... I suggest you implement the things mentioned in the blog I pointed you at.

    Comment


    • #3
      Thank you for your reply, I'm trying to use the SessionFactory directly as said in the blog post, but I'm getting LaizyInitializationException when trying to access the members from a loaded object.

      I found that after doing a commit() the session is closed, I think that is the cause of the LaizyInitializationException when accessing the members of the loaded object.

      If I don't use the beginTransaction() when doing a createQuery() an HibernateException is thrown with the message "createQuery is not valid without active transaction".

      I'm clueless, any ideas?


      This is part of the applicationContext.xml:

      Code:
         <!-- 4. conversation - persistence adapter -->
          <bean id="persistentContextFactory"
              class="com.umaloop.mailstat.db.HibernatePersistenceContextFactory">
            <property name="entityManagerFactory" ref="entityManagerFactory"/>
          </bean>
      
      	<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
      		<property name="sessionFactory" ref="entityManagerFactory"/>
      	</bean>
      
      	<bean id="entityManagerFactory"
      		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
      		<property name="configLocation"><value>classpath:hibernate.cfg.xml</value></property>
      		<property name="hibernateProperties">
      			<props>
      				<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
      				<prop key="hibernate.connection.release_mode">after_transaction</prop>
      			</props> 
      		</property>
      	</bean>

      And this is the way I'm trying to load a persisted object:

      Code:
      	public UserDto getUser(String username) {
      		UserDto user = null;
      		Session session = factory.getSession();
      		Transaction tx = null;
      		try {
      			tx = session.beginTransaction();
      			Query query = session.createQuery("from UserDto where username=:username");
      			query.setParameter("username", username);
      			
      			List<UserDto> users = (List<UserDto>) query.list();
      			if(users.size() == 1) {
      				user = users.get(0);
      			}
      			tx.commit();
      		}
      		catch (Exception e) {
      		     if (tx!=null) {
      		    	 tx.rollback();
      		     }
      		 }
      		return user;
      	}

      Comment


      • #4
        1) Let spring do the heavy work, don't manage your own transactions
        2) You have a TransactionManager but no transactional configuration
        3) The transactions should be defined on the service layer.
        4) Make sure you don't set the current_session_context property (unless you use JTA which you don't).

        Chapter 9 of the reference guide covers transactions. You can have different approaches here is a sample with annotations.

        Code:
        public class SomeServiceImpl implements SomeService {
        
          private UserDao userDao;
          
          @Transactional
          public UserDto loadUser(String username) {
            return userDao.getUser(username);
          }
        
        }
        your dao then looks like this, notice the fact that there is no transaction code!

        Code:
        public UserDto getUser(String username) {
        	UserDto user = null;
        	Session session = factory.getSession();
        	Query query = session.createQuery("from UserDto where username=:username");
        	query.setParameter("username", username);
        	return (UserDto) query.uniqueResult();
        }
        In your configuration add
        Code:
        <tx:annotation-driven />
        And you have transactions applied.

        Your LazyInitializationException can be fixed with an OpenSessionInViewFilter that keeps a hibernate Session open until after the page rendering.

        Comment


        • #5
          Marten, thank you for help I really appreciate your suggestions but my project's deadline is too close to make those kind of changes.

          Anyway I'll make a simple CRUD to test the spring managed transactions, I read the spring reference chapter about transactions, but I couldn't find how to know when a transaction was successful or not. In case of failure spring (or hibernate) will throw an Exception?

          Comment

          Working...
          X