从Hibernate会话中获取的连接应该关闭吗?

5

我需要手动关闭从Hibernate会话中获取的连接吗?

如果我这样做,我会关闭连接池中的一个连接吗?

如果我不这样做,Hibernate会自动关闭连接吗?

            Connection con = null;
            PreparedStatement ps = null;
            ResultSet rs = null;

            String query = "sql query";
            try {
                Session session = this.sessionFactory.getCurrentSession();
                con = session.connection();
                ps = con.prepareStatement(query);
                rs = ps.executeQuery();
                while (rs.next()) {
                    //read result set
                }
            } catch (SQLException exp) {
                log.error("Error: ", exp);
            } finally{
               if(ps != null)
                   ps.close();
               if(con != null)
                   con.close();  //Is this required?
            }

无论是流、连接池还是直接数据库访问,您都应该始终关闭任何连接。 - TheLostMind
3个回答

5
一般情况下,不应该关闭连接。Hibernate会话可能仍然希望在会话的生命周期后期使用相同的连接对象执行其他任务,如果关闭其连接,则会打断此操作。Hibernate负责管理连接对象的生命周期。
但是,在ConnectionReleaseMode.AFTER_STATEMENT启用且JDBC提供程序支持该模式的情况下,可以关闭连接。这种情况并不常见,因为必须处于自动提交模式才能正常工作。详见javadoc中的说明。

一般情况下,不应该关闭那个连接。你有什么来源可以强调这一点吗?有些人说我们应该总是关闭,因此我很困惑,我们应该关闭吗? - Sam YC
@GMsoF 是的,就是答案中链接的那个方法的Javadoc。 - Affe
我明白了。我自己也对Hibernate的连接和会话感到困惑。顺便说一下,如果我们在上述情况中提到Hibernate会话,我们需要关闭从getCurrentSession获取的Hibernate会话吗? - Sam YC
@GMsoF 这其实又是一个“看情况”的问题,但通常不需要。在现代大多数环境中,会话生命周期都是由容器管理的。除非你明确创建了一个会话,否则不需要显式地关闭它。 - Affe

1
Hibernate应该释放JDBC连接。默认情况下,JDBC连接会一直保持到会话被显式关闭或断开连接。对于应用服务器JTA数据源,请使用after_statement在每个JDBC调用后积极释放连接。对于非JTA连接,通常有意义的做法是在每个事务结束时释放连接,通过使用after_transaction。auto将为JTA和CMT事务策略选择after_statement,并为JDBC事务策略选择after_transaction。
例如:auto(默认)| on_close | after_transaction | after_statement

0

是的,你应该关闭连接。如果你正在使用连接池,你应该断开会话,这不会真正关闭它,但它会将其释放回池中。

对于非连接池。在javadoc中指出

注意:当Connection对象被垃圾收集时,它会自动关闭。某些致命错误也会关闭Connection对象。

然而,由于它将被关闭,最好还是自己处理。


2
你能提供一个来源来支持你的回答吗?@Affe的回答说不要关闭它。现在我很困惑。 - atripathi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接