Spring 3 MVC Hibernate 3.5.4 hibernateTemplate non-closing connections (non-transactional)

We use Spring MVC 3.0.5.RELEASE with Hibernate 3.5.4-Final without transactions. Each time we access the database through hibernateTemplate, it creates a new connection and, apparently, never closes them.

UPDATE: we set maxActive and maxIdle to 5. The application will freeze when it tries to open the 6th connection. We allow 100 mysql connections.

Our hibernateTemplate is Autowired, so we do not directly manage these connections. Any ideas on making sure these connections are closed?

Here is our Spring configuration for sleep mode:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName">
        <value>${jdbc.driverClassName}</value>
    </property>
    <property name="url">
        <value>${jdbc.url}</value>
    </property>
    <property name="username">
        <value>${jdbc.username}</value>
    </property>
    <property name="password">
        <value>${jdbc.password}</value>
    </property>
    <property name="maxActive">
        <value>5</value>
    </property>
    <property name="maxIdle">
        <value>5</value>
    </property>
    <property name="removeAbandoned">
        <value>true</value>
    </property>
    <property name="removeAbandonedTimeout">
        <value>30</value>
    </property>
</bean>

<alias name="dataSource" alias="userInfoDataSource"/>

<!-- Hibernate SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource">
        <ref local="dataSource"/>
    </property>
    <property name="packagesToScan" value="com.domain"/>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.connection.release_mode">after_statement</prop>
            <prop key="hibernate.transaction.flush_before_completion">true</prop>                
        </props>
    </property>
</bean>

<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>

Here is our implementation of HibernateRepository:

package com.dataAccess.impl;

import org.hibernate.criterion.DetachedCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public abstract class HibernateRepositoryImpl<T> implements com.dataAccess.Repository<T> {

  @Autowired
  protected HibernateTemplate hibernateTemplate;

  public List<T> find(String query) {
    return hibernateTemplate.find(query);
  }

  @Override
  public void saveOrUpdate(T ENTITY) {
    hibernateTemplate.saveOrUpdate(ENTITY);
  }

  @Override
  public List<T> find(DetachedCriteria criteria) {
    return hibernateTemplate.findByCriteria(criteria);
  }

  @Override
  public void delete(T ENTITY) {
    hibernateTemplate.delete(ENTITY);
  }
}

Here is an example of ours that we use, which seems to flow in connections:

package com.dataAccess.impl;

import com.domain.Trigger;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public class TriggerRepository extends HibernateRepositoryImpl<Trigger> {
  public List<Trigger> getActiveTriggers(Integer patientId) {
    DetachedCriteria findActiveTriggers = DetachedCriteria.forClass(Trigger.class).add(
        Restrictions.and(
            Restrictions.eq("patientId", patientId),
            Restrictions.eq("active", true)
        )
    );
    return super.find(findActiveTriggers);
  }
  public List<Trigger> getInActiveTriggers(Integer patientId) {
    DetachedCriteria findActiveTriggers = DetachedCriteria.forClass(Trigger.class).add(
        Restrictions.and(
            Restrictions.eq("patientId", patientId),
            Restrictions.eq("active", false)
        )
    );
    return super.find(findActiveTriggers);
  }

  public Trigger get(Integer triggerId) {
    return hibernateTemplate.get(Trigger.class, triggerId);
  }
}
+3
3

, , , - ( ) . , , Hibernate/ Spring .

, , :

connectionManager.getConnection().prepareStatement(..).<whatever>

, getConnection() , , .

+2

, transactionManager, Hibernate HibernateRepositoryImpl.

, , , ​​ - Hibernate, - , , SQL- , , hibernate.transaction.flush_before_completion true.

0

Also make sure you are not creating more than one instance HibernateTemplate, I

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("META-INF/spring/applicationContext.xml");
Object o=context.getBean("hibernateTemplate");

The object oshould be cached somewhere and returned when your application code requests an instance HibernateTemplate.

thank

0
source

All Articles