在我们的项目中,我们将Spring更新为4.3.14.RELEASE
,将Hibernate更新为4.3.11.Final
,因为我们已经开始看到两个警告:
WARN JDBC重置的连接与最初准备的连接不一样 - 请确保使用连接释放模式ON_CLOSE(默认值)并运行Hibernate 4.2+(或将HibernateJpaDialect的prepareConnection标志切换为false
ON_CLOSE
,这是我们不想要的 - 当我们的应用程序负载很重时,它会停止释放连接并且应用程序卡住了。这适用于释放模式AFTER_TRANSACTION。 prepareConnection
标记切换为false
会怎样?我试图在Hibernate配置中找到这样的标志,但无法找到它。GooGooStatementCache:441 - Multiply prepared statement!
编辑:我将Hibernate更新为5.2.13.Final
。
答案 0 :(得分:4)
以下是多重准备语句的解释(来自GooGooStatementCache source):
此连接已经准备了相同的声明, 并且其他实例尚未关闭,因此语句池 必须准备第二个PreparedStatement对象而不是重用 先前缓存的Statement。新的Statement将被缓存,以防万一 您经常需要多份本声明。
在英语中,这意味着PreparedStatement
在Connection
检出同一PreparedStatement
之前从Connection
签出了Thread
。这是不寻常的。只有一个客户端Connection
通常一次与PreparedStatement
进行交互,如果需要多次,通常会重复使用相同的close()
(重置其参数)。可能发生这种情况的最可能原因是因为应用程序没有PreparedStatement
它打开的Connection
,依靠c3p0在close()-ing
签入时清除它们。
在任何情况下,它都不是正确性问题,c3p0会很好地处理这个案子。但它可能反映了可以稍微清理的代码(在使用后立即通过PreparedStatement
PreparedStatement
或重新使用它们)在内存和资源使用方面更有效。如果您使用的是当前版本(0.9.5.2),c3p0应该会向您显示有问题的Connection
的文本。
我不知道为什么你会看到Spring / Hibernate警告。 c3p0已签出Connection
是代理,但其身份在其客户端可见生命周期内不会发生变化。看一下source,在获得与Session
相关联的Session
时会有一些反思和间接,然后将其与已检出的Connection
进行比较。即使在使用Connection
和Session
时,某些内容也可能导致{{1}}刷新其关联的{{1}}?我希望我能得到更多帮助,但我不确定发生了什么。
答案 1 :(得分:2)
通过使用Tomcat JDBC Pool,我遇到了同样的问题。
问题在春季出现,因为他们在351行进行了相等性检查 HibernateJpaDialect
比较是在连接池(在您的情况下为Tomcat Pool或c3p0)代理的连接上完成的。
如果您设置ON_CLOSE(休眠中的旧行为),则仅在重置/关闭会话时才会关闭连接,这不会引起任何问题,但可能会改变性能,特别是如果客户端将Hibernate会话保持打开一段时间。 / p>
如果设置(默认)AFTER_TRANSACTION,则在事务完成之后和会话关闭之前释放连接。第301行JdbcCoordinatorImpl
通常,此方法resetSessionState()检查是否两次关闭连接
line 349 if (this.preparedCon != null && this.session.isConnected())
出现问题是因为在第一个发行版(事务之后)期间(由连接池代理的)连接已更改,并且未满足相等性导致警告消息。 此警告消息是误报
答案 2 :(得分:0)
您可以尝试使用属性hibernate.connection.handling_mode
hibernate.connection.handling_mode=DELAYED_ACQUISITION_AND_HOLD
如果您使用的是JTA
hibernate.connection.handling_mode=DELAYED_ACQUISITION_AND_RELEASE_AFTER_TRANSACTION
或
hibernate.connection.handling_mode=DELAYED_ACQUISITION_AND_RELEASE_AFTER_STATEMENT
请参阅此springframework javadoc部分 setPrepareConnection
答案 3 :(得分:0)
通过以下设置禁用org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor
:
spring:
jpa:
open-in-view: false
hibernate:
connection:
release_mode: on_close # default mode, you can remove this line