【问题标题】:Hibernate cannot close connection for PostgresqlHibernate 无法关闭 Postgresql 的连接
【发布时间】:2016-06-07 17:09:35
【问题描述】:

我正在使用 Heroku 远程 PostgreSQL 数据库,在我的应用程序中,我还使用 hibernate 和 c3p0。已经设置了最大连接,使用后关闭连接,但所有这些都无法关闭数据库中的空闲连接。我的代码中的错误?因为如果我只更改 url 并连接到本地 MySQL,它就可以工作。所以我认为 PostgreSQL 很特别。还是因为heroku远程数据库的限制?

hibernate.cfg.xml 是这样的。我将其更改为适应本地mysql,它确实关闭了连接。

<session-factory>

    <!-- hibernate connection configuration -->
    <property name="connection.url">jdbc:mysql://localhost/website</property>
    <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="connection.username">root</property>
    <property name="connection.password">root</property>

    <!-- hibernate performance configuration -->
    <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="format_sql">true</property>
    <property name="hbm2ddl.auto">update</property>
    <property name="hibernate.temp.use_jdbc_metadata_defaults">false</property>
    <property name="show_sql">true</property>

    <!-- c3p0 configuration -->
    <property name="c3p0.acquire_increment">1</property>
    <property name="c3p0.idle_test_period">10</property>
    <property name="c3p0.max_statements">3</property>
    <property name="c3p0.max_size">2</property>
    <property name="c3p0.min_size">1</property>
    <property name="c3p0.timeout">90</property>
    <property name="transaction.auto_close_session">true</property>
    <property name="idleConnectionTestPeriod">60</property>
    <property name="maxIdleTime">30</property>





    <!-- presistance objects -->
    <mapping class="pojo.WebSiteCommentPOJO"/>

</session-factory>

HibernateUtil 是这样的:

    public class HibernateUtils {

private static SessionFactory sessionFactory;

public static SessionFactory getSessionFactory() {
        if (sessionFactory != null) {
            return sessionFactory;
        }
    Configuration conf = new Configuration().configure();

    StandardServiceRegistryBuilder serviceRegistryBuilder = new StandardServiceRegistryBuilder();

    serviceRegistryBuilder.applySettings(conf.getProperties());

    /*ServiceRegistry serviceRegistry = serviceRegistryBuilder.build();*/

    SessionFactory sf = conf.buildSessionFactory();
    return sf;
}

public static Session getSession() {
    return getSessionFactory().openSession();
}

}

下面的代码是我如何使用hibernate的。

public WebSiteComment getSingle(int id) {
    Session ss = HibernateUtils.getSession();
    ss.beginTransaction();
    WebSiteCommentPOJO w = ss.get(WebSiteCommentPOJO.class,id);
    ss.getTransaction().commit();

    return new WebSiteComment(w.getId(), w.getComment(), w.getEmail(), w.getDate());
}

【问题讨论】:

    标签: hibernate postgresql connection c3p0


    【解决方案1】:

    最后我修正了我的错误。我从here 找到了一个标准的HibernateUtil.java 现在我的代码是这样的。

    private static final SessionFactory sessionFactory;
    
    static {
        try {
            sessionFactory = new Configuration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }
    
    public static SessionFactory getSessionFactory(){
    return sessionFactory;
    }
    

    关键的区别可能是sessionFactoryfinal;但我认为在我之前的版本中,初始化后,我仍然返回相同的 sessionFactory 对象。 此外,我使用了一些不同的方法来获取SessionFactory

    在此花费 2 天时间,感谢 v.ladynev 的帮助。希望我的解决方案会有所帮助。

    【讨论】:

      【解决方案2】:

      您需要关闭session 才能关闭连接。当事务提交时,会话和连接没有关闭,因为您可以开始新事务或对会话执行其他操作。很可能,MySQL 有大量可以打开的连接。当然,Heroku 的连接数量有限。

      使用finally 块以任何方式关闭session。您可以使用this 模式来处理会话。

      只需执行此操作即可配置会话工厂

      SessionFactory sf = new Configuration().configure().buildSessionFactory();

      而且你需要回滚事务以防出错。

      更新

      我的答案可能不是很正确,因为使用了

      &lt;property name="transaction.auto_close_session"&gt;true&lt;/property&gt;

      【讨论】:

      • @Alvin 在最简单的情况下使用getSession()。请在您的问题中添加带有close 的代码。
      • 由于我使用ss.beginTransaction();ss.getTransaction().commit();,他们将为我关闭会话。顺便说一句,相同的代码适用于本地 MySQL。
      • @Alvin 对不起。看起来,由于&lt;property name="transaction.auto_close_session"&gt;true&lt;/property&gt;,连接已关闭。但请尝试手动关闭它。
      • 连接池的 max_size 也起作用
      • 问题是否可能是您在本地没有遇到的网络故障?例如,在上面的代码中,如果在Session ss = HibernateUtils.getSession(); 之后但在ss.getTransaction().commit(); 完成之前的任何地方出现异常,则会话不会自动关闭并且您会泄漏连接。也许确保事务总是通过 finally 块解决。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-05
      • 1970-01-01
      • 1970-01-01
      • 2016-11-27
      • 1970-01-01
      • 1970-01-01
      • 2012-03-29
      相关资源
      最近更新 更多