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是Autowired,因此我们不直接管理这些连接。 关于如何确保这些连接关闭的任何想法?
这是我们用于hibernate的弹簧配置:
${jdbc.driverClassName} ${jdbc.url} ${jdbc.username} ${jdbc.password} 5 5 true 30 org.hibernate.dialect.MySQLDialect true after_statement true
这是我们的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 implements com.dataAccess.Repository { @Autowired protected HibernateTemplate hibernateTemplate; public List find(String query) { return hibernateTemplate.find(query); } @Override public void saveOrUpdate(T ENTITY) { hibernateTemplate.saveOrUpdate(ENTITY); } @Override public List 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 { public List 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 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(..).
getConnection()调用可能会打开一个新连接,并且每个准备好的语句都有一个更改才能关闭。
我相信如果您没有使用transactionManager,那么您应该在HibernateRepositoryImpl
类中的每个操作之后关闭Hibernate会话。
你在大多数情况下可能会被认为是一个错误 – 你正在打开新的Hibernate会话,但它们永远不会被关闭 – 你看到实际对数据库执行的SQL语句的唯一原因是因为你有hibernate.transaction.flush_before_completion
属性设置为true。
另外请确保您没有创建多个HibernateTemplate
实例,我
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("META-INF/spring/applicationContext.xml"); Object o=context.getBean("hibernateTemplate");
对象o
必须在某处缓存,并在您的应用程序代码要求hibernatetemplate
实例时返回。
谢谢