Hibernate:关闭会话工厂不会关闭c3p0连接池

我最近开始在应用程序中使用hibernate和c3p0作为ORM。但是,当我关闭会话工厂时,连接池不会自行关闭!这是我的应用程序中 唯一

可以进行会话操作的地方。

    StatelessSession session = null;

Transaction transaction = null;

try {

session = sessionFactory.openStatelessSession();

transaction = session.beginTransaction();

List<Thingy> list = session.getNamedQuery("getAvailableThingy").list();

transaction.commit();

return list;

} catch (Exception error) {

if (transaction != null) {

transaction.rollback();

}

throw error;

} finally {

if (session != null) {

session.close();

}

}

这是我的hibernate.cfg.xml配置文件

<?xml version='1.0' encoding='utf-8'?>

<!DOCTYPE hibernate-configuration PUBLIC

"-//Hibernate/Hibernate Configuration DTD//EN"

"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

<session-factory>

<property name="hibernate.connection.driver_class">org.postgresql.Driver</property>

<property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>

<property name="javax.persistence.validation.mode">none</property>

<property name="hibernate.connection.release_mode">after_transaction</property>

<property name="hibernate.c3p0.minPoolSize">1</property>

<property name="hibernate.c3p0.maxPoolSize">2</property>

<property name="hibernate.c3p0.acquireIncrement">1</property>

<property name="hibernate.c3p0.initialPoolSize">1</property>

<property name="hibernate.c3p0.timeout">30</property>

<property name="hibernate.c3p0.maxIdleTimeExcessConnections">5</property>

<property name="hibernate.c3p0.idleConnectionTestPeriod">300</property>

</session-factory>

</hibernate-configuration>

请注意,空闲连接非常短的原因是它是我尚未通过集成测试的唯一方法。他们经常打开和关闭会话工厂,因此我总是用尽所有连接。正如我们在项目开始时一样,从长远来看,我认为这不是一个非常可持续的策略。

需要注意的“有趣”是,尽管我将初始连接池设置为一个,但c3p0仍然尝试在启动时打开两个连接。我的猜测是某个隐藏的会话在某个地方不会关闭(但是在哪里?击败了我)。

那么,如何才能使那个烦人的连接池关闭呢?

附加信息:我如何创建和销毁会话工厂

import static com.google.common.base.Preconditions.*;

import javax.inject.Inject;

import javax.inject.Provider;

import javax.inject.Singleton;

import org.hibernate.SessionFactory;

import org.hibernate.cfg.Configuration;

import org.hibernate.service.ServiceRegistry;

import org.hibernate.service.ServiceRegistryBuilder;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import com.google.inject.Provides;

@Singleton

public class PostgisConnection implements Provider<SessionFactory>, AutoCloseable {

private final Logger logger = LoggerFactory.getLogger(getClass());

private final ConnectionInfo connectionInfo;

private SessionFactory sessionFactory = null;

@Inject

public PostgisConnection(ConnectionInfo connectionInfo) {

this.connectionInfo = connectionInfo;

}

public AutoCloseable open() {

checkState(sessionFactory == null, "Connections to postgis are already open");

logger.info("Creating sessionFactory for connection to postgis: {}", connectionInfo.getJdbcUrl());

sessionFactory = newPostgisSessionFactory(connectionInfo);

return this;

}

@Override

public void close() throws Exception {

try {

if (sessionFactory != null) {

logger.info("Closing sessionFactory for postgis: {}", connectionInfo.getJdbcUrl());

sessionFactory.close();

checkState(sessionFactory.isClosed(), "Session factory should be closed at this point");

}

} catch (Exception error) {

logger.error("Error closing SessionFactory", error);

}

}

@Provides

public SessionFactory get() {

return sessionFactory;

}

public static SessionFactory newPostgisSessionFactory(ConnectionInfo connectionInfo) {

Configuration configuration = configurationWith(connectionInfo);

return configuration.buildSessionFactory(registryFrom(configuration));

}

private static Configuration configurationWith(ConnectionInfo connectionInfo) {

Configuration configuration = new Configuration();

setConnectionInfo(connectionInfo, configuration);

configuration.addURL(PostgisConnection.class.getResource("mapping.hbm.xml"));

configuration.configure(PostgisConnection.class.getResource("hibernate.cfg.xml"));

return configuration;

}

private static void setConnectionInfo(ConnectionInfo connectionInfo, Configuration configuration) {

configuration.setProperty("hibernate.connection.url", connectionInfo.getJdbcUrl());

configuration.setProperty("hibernate.connection.username", connectionInfo.getUsername());

configuration.setProperty("hibernate.connection.password", connectionInfo.getPassword());

}

private static ServiceRegistry registryFrom(Configuration configuration) {

return new ServiceRegistryBuilder()

.applySettings(configuration.getProperties())

.buildServiceRegistry();

}

}

  • Hibernate版本:4.1.10.Final
  • C3p0版本:0.9.1.2

回答:

我遇到了同样的问题,并成功使用了此错误报告中提供的解决方法:

private void closeSessionFactory(SessionFactory factory) { 

if(factory instanceof SessionFactoryImpl) {

SessionFactoryImpl sf = (SessionFactoryImpl)factory;

ConnectionProvider conn = sf.getConnectionProvider();

if(conn instanceof C3P0ConnectionProvider) {

((C3P0ConnectionProvider)conn).close();

}

}

factory.close();

}

您必须引用hibernate-c3p0-4.xx jar。

以上是 Hibernate:关闭会话工厂不会关闭c3p0连接池 的全部内容, 来源链接: utcz.com/qa/408567.html

回到顶部