简体   繁体   English

Spring 3 MVC Hibernate 3.5.4 hibernateTemplate没有关闭连接(非事务性)

[英]Spring 3 MVC Hibernate 3.5.4 hibernateTemplate not closing connections (non-transactional)

We are using Spring MVC 3.0.5.RELEASE with Hibernate 3.5.4-Final without transactions. 我们在没有事务的情况下使用Spring MVC 3.0.5.RELEASE和Hibernate 3.5.4-Final。 Every time we access the database through the hibernateTemplate it creates a new connection and seemingly never closes them. 每次我们通过hibernateTemplate访问数据库时,它都会创建一个新连接,并且似乎永远不会关闭它们。

UPDATE: we've set maxActive and maxIdle to 5. The application will hang when it tries to open the 6th connection. 更新:我们将maxActive和maxIdle设置为5.应用程序在尝试打开第6个连接时将挂起。 We allow 100 mysql connections. 我们允许100个mysql连接。

Our hibernateTemplate is Autowired, so we're not directly managing these connections. 我们的hibernateTemplate是Autowired,因此我们不直接管理这些连接。 Any ideas on how to make sure these connections are closed? 有关如何确保这些连接关闭的任何想法?

Here's our spring configuration for hibernate: 这是我们用于休眠的弹簧配置:

<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 HibernateRepository implementation: 这是我们的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 our we are using it, which seems to leak 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);
  }
}

The problem ended up being some legacy code which called was chaining several methods together, where the method in the middle of creating the connection -- so the connection was never getting assigned (tough to spot) nor was it ever getting closed. 问题最终是一些遗留代码被称为将多个方法链接在一起,其中创建连接的方法 - 所以连接永远不会被分配(很难发现),也不会被关闭。 This code was indirectly getting loaded and I wrongly suspected my Hibernate/Spring configuration to be at fault. 这段代码是间接加载的,我错误地怀疑我的Hibernate / Spring配置有问题。

If you hit similar issues be wary of lines of code that read: 如果遇到类似问题,请注意以下代码行:

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

The getConnection() call likely opens a new connection and it nor the prepared statement every have a change to get closed. getConnection()调用可能会打开一个新连接,并且每个准备好的语句都有一个更改才能关闭。

I believe that if you aren't using a transactionManager then you should be closing the Hibernate session after each of the operations in your HibernateRepositoryImpl class. 我相信如果您没有使用transactionManager,那么您应该在HibernateRepositoryImpl类中的每个操作之后关闭Hibernate会话。

What you have would probably be considered a bug in most situations - you are opening new Hibernate sessions, but they are never being closed - the only reason why you are seeing the SQL statements actually executed against the database is because you have the hibernate.transaction.flush_before_completion property set to true. 你在大多数情况下可能会被认为是一个错误 - 你正在打开新的Hibernate会话,但它们永远不会被关闭 - 你看到实际对数据库执行的SQL语句的唯一原因是因为你有hibernate.transaction.flush_before_completion属性设置为true。

Also please make sure that you are not creating more than one instance of HibernateTemplate , i 另外请确保您没有创建多个HibernateTemplate实例,i

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

The object o has to be cached somewhere and returned when your app code is asking for instance of hibernatetemplate . 对象o必须在某处缓存,并在您的应用程序代码要求hibernatetemplate实例时返回。

Thanks 谢谢

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Spring MVC + Hibernate:没有Hibernate Session绑定到线程,配置不允许在这里创建非事务性的 - Spring MVC + Hibernate: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here Spring:没有Hibernate Session绑定到线程,并且配置不允许在此处创建非事务性会话 - Spring: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here Java Spring:mongodb的事务版本和非事务版本的兼容性 - Java Spring: Compatibility for both transactional and non-transactional versions of mongodb 例外-非交易 - Exception - non-transactional 延迟加载在Hibernate的非事务类/方法中工作 - Lazy loading working in non-transactional class/method in Hibernate 如何在Spring中创建非事务性JUnit集成测试? - How to create non-transactional JUnit integration tests in Spring? 寻求针对(3.0.5)的Spring解决方案:没有Hibernate Session绑定到线程,并且配置不允许在此处创建非事务性会话 - Seeking a Spring (3.0.5) Solution for: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here Spring Boot-从非事务性原因更新中校准事务性方法 - Spring Boot - caling transactional method from non-transactional cause update 在另一个实例中从事务方法调用 spring 非事务方法时,事务是否得到传播? - When calling a spring Non-Transactional method from a Transactional Method in another instance, does the transaction get propagated? 没有Hibernate会话绑定到线程,配置不允许在这里创建非事务性的 - No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM