Spring 3 MVC Hibernate 3.5.4 hibernateTemplate不关闭连接(非事务性)
问题内容:
我们在没有事务的情况下将Spring MVC 3.0.5.RELEASE与Hibernate
3.5.4-Final一起使用。每次我们通过hibernateTemplate访问数据库时,它都会创建一个新连接,并且似乎永远不会关闭它们。
更新:我们已经将maxActive和maxIdle设置为5。尝试打开第6个连接时,应用程序将挂起。我们允许100个mysql连接。
我们的hibernateTemplate是自动连线的,因此我们不直接管理这些连接。关于如何确保这些连接是否关闭的任何想法?
这是我们用于hibernate的spring配置:
<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>
这是我们的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);
}
}
这是我们正在使用它的示例,它似乎泄漏了连接:
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);
}
}
问题答案:
问题最终是一些遗留代码,这些代码将多个方法链接在一起,其中该方法位于创建连接的中间-
因此,从未分配连接(很难发现),也从未关闭连接。这段代码是间接加载的,我错误地怀疑我的Hibernate / Spring配置有问题。
如果遇到类似问题,请警惕以下代码行:
connectionManager.getConnection().prepareStatement(..).<whatever>
调用getConnection()可能会打开一个新连接,并且该准备连接或已准备好的语句都需要更改才能关闭。