HHH000387 Hibernate警告的含义是什么?

27
我刚刚更新到 Hibernate 4.0,看到日志文件中出现了警告信息:

HHH000387: ResultSet 的语句未注册

这是什么意思?我应该担心吗?


2
我也想知道这个问题的答案。 - Drew Wills
5个回答

1

查看抛出此错误的JdbcResourceRegistryImpl类的源代码,我个人认为将其记录为WARN级别过于严重;除非有一种方法可以将所有Statement隐式注册为Hibernate/框架配置的一部分,否则最多应该是INFO。

我不清楚为什么需要注册Statement,但如果它只是Hibernate内部工作的问题,那么经常警告API用户就是一个错误,对吧?


1
我不会太担心。无论如何,看起来API的用户无法避免这个消息。日志记录是在org.hibernate.engine.jdbc.internal.JdbcResourceRegistryImpl中完成的。根据文档

JdbcResourceRegistry的主要功能是确保资源得到清理。

简短地查看代码可以发现,这样的消息在两种情况下被记录:
  1. 通过register方法注册ResultSet,但未注册语句。
  2. 通过release方法释放ResultSet,但未注册语句。

1
这个日志信息表明 ResultSet.getStatement() 方法没有返回最初用于创建 ResultSetStatement。这可能是由于 JDBC 包装器中存在两个 Statement 对象:一个包装器/装饰器和底层的 Statement。这也可能表示存在内存泄漏。
在我的项目中,我有自己的 JDBC 包装器进行测试。我通过确保 getStatement() 返回原始的 Statement 代理(而不是新的代理),而不是委托给底层的 ResultSet(这将返回底层的 Statement)来修复了我的 ResultSet 包装器中的此警告。
任何产生类似警告的 JDBC 包装器都可能需要类似的修复。(类似的问题和解决方法可能适用于方法 Statement.getConnection()。)
顺便说一下,这里有一个关于此日志记录的错误报告:https://hibernate.atlassian.net/browse/HHH-8210

0
在我的情况下,这个警告是一个巨大性能泄漏的指标!我有带有@oneToOne映射的Hibernate POJO对象。对于一个表格,它可以正常工作,没有警告:它发送一个请求到MySQL服务器以获取所有记录,然后为每个连接的表格发送一个请求。
对于我遇到此错误的POJO(当未找到@oneToOne时):它发送一个初始请求以获取所有对象的列表,然后每次为每个记录发送新的映射表的请求。
所以,假设我在测试数据库中有2000条记录。还有3个@oneToOne映射表。
在良好的情况下,它发送1个请求以获取列表和3个请求以获取映射表。
在警告的情况下,它发送1个初始请求以获取列表。然后为数据库中的每个记录发送3个请求以获取映射信息!因此,每个用户每次调用@Controller(Spring MVC)都会产生1999 * 3 = 5997个额外的请求。
当Web应用程序和MySQL服务器在同一台服务器上时,我没有注意到它。

0

你配置了连接池吗?我也有同样的警告。但如果我在maven依赖中添加了c3p0,并在hibernate.cfg.xml中正确配置它,那么警告就消失了。


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