Spring未在JBoss EAP 6上释放/重用Hibernate会话
我有一个使用Hibernate4的Spring应用程序。Hibernate配置位于my application-config.xml中,如下所示:Spring未在JBoss EAP 6上释放/重用Hibernate会话,spring,hibernate,jdbc,jboss6.x,Spring,Hibernate,Jdbc,Jboss6.x,我有一个使用Hibernate4的Spring应用程序。Hibernate配置位于my application-config.xml中,如下所示: <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <propert
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">validate</prop>
</props>
</property>
<property name="packagesToScan">
<list>
<value>com.mycompany.esb.jpa</value>
</list>
</property>
</bean>
下面是我为这个例子简化的一个类
package com.mycompany.esb.jpa.dao;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.springframework.stereotype.Component;
import com.mycompany.esb.jpa.entity.ServicesEntity;
@Component("servicesDAO")
public class ServicesDAOImpl extends HibernateBaseDAO implements ServicesDAO {
@Override
public List<ServicesEntity> getAllServices(double daysPrevious, double hoursToShow) {
try {
Query query = getSession().createQuery("FROM ServicesEntity e "
+ "WHERE e.responseTime >= (sysdate - (" + daysPrevious + " + " + hoursToShow + "/24)) "
+ "AND e.responseTime < (sysdate - " + daysPrevious + ") "
+ "GROUP BY e.domainName, e.serviceName, e.operationName, e.elapsedTime, e.serviceTimestamp, "
+ "e.id, e.responseTimeAverage, e.responseTime, e.requestSizeAverage, e.responseSizeAverage, e.requestCount "
+ "ORDER BY e.domainName, e.serviceName, e.operationName, e.serviceTimestamp");
@SuppressWarnings("unchecked")
List<ServicesEntity> services = (List<ServicesEntity>) query.list();
return services;
} catch (HibernateException hex) {
hex.printStackTrace();
}
return null;
}
}
我遇到的问题是,当部署到JBoss EAP时,每次调用getAllServices方法时,它都会从JDBC池中获取一个新连接,并且永远不会释放它。因此,当容器JDBC池最多有5个连接时,在5次查询之后,后续查询会超时,因为没有可用的连接。连接池不应该由Hibernate SessionFactory对象管理吗?是否需要显式关闭连接 正如用户Orid最初指出的:他随后删除了他的答案 这是因为您调用sessionFactory.openSession;在…内 在基类中获取会话,并且从不释放会话和 通过调用close进行连接 您应该改用sessionFactory.getCurrentSession; 哪一个将会话固定到JTA事务/线程取决于您的 数据源事务资源管理配置 此外,还应使用注释对getAllServices进行注释 @TransactionalreadOnly=对于正确的事务和连接为true 获取/发布管理 我还必须将@EnableTransactionManagement注释添加到我的ServicesDAOImpl类中,并在JBoss EAP中启用CCM 因此,我的新ServicesDAOImpl类如下所示:
package com.mycompany.esb.jpa.dao;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.springframework.stereotype.Component;
import com.mycompany.esb.jpa.entity.ServicesEntity;
@EnableTransactionManagement
@Component("servicesDAO")
public class ServicesDAOImpl extends HibernateBaseDAO implements ServicesDAO {
@SuppressWarnings("unchecked")
@Transactional(readOnly=true)
@Override
public List<ServicesEntity> getAllServices(double daysPrevious, double hoursToShow) {
Query query = getSession().createQuery("FROM ServicesEntity e "
+ "WHERE e.responseTime >= (sysdate - (" + daysPrevious + " + " + hoursToShow + "/24)) "
+ "AND e.responseTime < (sysdate - " + daysPrevious + ") "
+ "GROUP BY e.domainName, e.serviceName, e.operationName, e.elapsedTime, e.serviceTimestamp, "
+ "e.id, e.responseTimeAverage, e.responseTime, e.requestSizeAverage, e.responseSizeAverage, e.requestCount "
+ "ORDER BY e.domainName, e.serviceName, e.operationName, e.serviceTimestamp");
try {
return (List<ServicesEntity>) query.list();
} catch (HibernateException hex) {
hex.printStackTrace();
}
return null;
}
}
package com.mycompany.esb.jpa.dao;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
public abstract class HibernateBaseDAO {
@Autowired
protected SessionFactory sessionFactory;
protected Session getSession() {
return sessionFactory.getCurrentSession();
}
}
为什么要这样做?您没有事务设置,在该设置旁边,您执行openSession,表示您希望管理自己的会话。设置事务并改用getCurrentSession。
package com.mycompany.esb.jpa.dao;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
public abstract class HibernateBaseDAO {
@Autowired
protected SessionFactory sessionFactory;
protected Session getSession() {
return sessionFactory.getCurrentSession();
}
}