What does HHH000387 Hibernate warning mean?

2019-03-17 11:36发布

问题:

I have just updated to Hibernate 4.0 and am seeing the warning message :

HHH000387: ResultSet's statement was not registered

in my log files. What does this mean, and should I be worried?

回答1:

I would not worry too much. In any case it looks like it is not in API's users hands to avoid this message. Logging is done in the org.hibernate.engine.jdbc.internal.JdbcResourceRegistryImpl. According documentation:

The main function of a JdbcResourceRegistry is to make sure resources get cleaned up.

Short look to the code tells, that such a message is logged in two situations:

  1. ResultSet is registered via register-method, and statement is not registered.
  2. ResultSet is released via release-method and statement is not registered.


回答2:

Looking at the source for the JdbcResourceRegistryImpl class that throws this error, I personally think having it log at WARN level is excessive; it should be INFO at most, unless there's a way to have all Statements implicitly registered as part of a Hibernate/framework configuration.

It's not clear to me why a Statement should be registered, but if it's only a concern of the inner workings of Hibernate then routinely warning API users about it is a bug, right?



回答3:

This log message is a sign that ResultSet.getStatement() doesn't return the Statement which was originally asked to create the ResultSet. (It may also indicate a memory leak.) This can happen when using a JDBC wrapper, because there are two Statement objects: a wrapper/decorator and the underlying Statement.

In my project, I have my own JDBC wrapper for testing. I fixed this warning in my ResultSet wrapper by ensuring that getStatement() returns the original Statement proxy (not a new proxy), rather than delegating to the underlying ResultSet (which would return the underlying Statement).

Any JDBC wrapper which is producing similar warnings could probably use a similar fix. (A similar problem and fix may apply to the method Statement.getConnection().)

By the way, there is a bug report for this logging here: https://hibernate.atlassian.net/browse/HHH-8210



回答4:

Did you configured connection pool? I've got the same warning. But if I added c3p0 in my maven dependency and get it correctly configured in hibernate.cfg.xml. The warning disappears.



回答5:

In my case this warning was an indicator of huge performance leak! I have hibernate POJO objects with @oneToOne mapping. For one table it works fine and no warnings: it sends one request to MySQl server for getting all the records and then for one requests for each joined table. For POJO where I'm getting this error (when no @oneToOne found): it sends one initial request for getting a list of all objects and then every time send new and new requests for mapped tables for each record.

So, let's say I have 2000 records in my test DB. And 3 @oneToOne mapped tables.

In a good case, it sends 1 request for getting a list and 3 requests for getting mapped tables.

In the case of a warning, it sends 1 initial request for getting list. Then send 3 requests for getting mapped info for each of 2000 records in DB! So 1999*3=5997 additional requests for each user for each call the @Controller (Spring MVC).

I hadn't noticed it while the web application and MySQL server were on the same server.