Generated properties leak prepared statements in Hibernate 3.2.3 and higher.

Description

The fix for HHH-2393, in combination with a change to AbstractBatcher 11333 to the Hibernate 3.2 branch (comment is "sybase testsuite"), created a PreparedStatement leak for generated properties.

The reason is that, in revision 11333, org.hibernate.jdbc.AbstractBatcher#closeQueryStatement() was changed to check for the existence of the prepared statement in the statementsToClose collection instead of closing it unconditionally. The fix for (revision 11117 in the Hibernate 3.2 branch) modified org.hibernate.persister.entity.AbstractEntityPersister#processGeneratedProperties() to make it use org.hibernate.jdbc.AbstractBatcher#closeQueryStatement() instead of org.hibernate.jdbc.AbstractBatcher#closeStatement(), which closes the statement without checking the statementsToClose collection. This is a problem because the statement in AbstractEntityPersister#processGeneratedProperties() is created with AbstractBatcher#prepareSelectStatement(), which does not add the statement to the statementsToClose collection.

The attached patch to org.hibernate.persister.entity.AbstractEntityPersister changes processGeneratedProperties() back to using AbstractBatcher#closeStatement() and obtains the result set through ResultSet#executeQuery() instead of using the batcher. This fixes the prepared statement leak and matches other usages of AbstractBatcher#prepareSelectStatement(), which also avoid using the batcher for their result sets. It also makes the same change in AbstractEntityPersister#initializeLazyPropertiesFromDatastore() becuase it has exactly the same problem.

No existing test cases are broken by the attached patch. I investigated ways to write a test case to explicitly verify that the result sets and statements were all being closed. However, because the counts in AbstractBatcher are private, and I do not know of a generic way to obtain counts through the JDBC API, I could not figure out a good way to do so without using reflection to access the private fields, which none of the existing test cases seem to do.

The bug was discovered when running my web app against Oracle, which runs out of cursors when connections are leaked – not exactly a practical way to write a test case, but sufficient to prove that the bug exists and is fixed by the patch.

Environment

Hibernate 3.2.2-4sp1, Oracle 10g (Oracle9Dialect)

Activity

Show:
Gail Badner
October 19, 2007, 12:37 AM

Sorry, I don't know of a workaround for this issue.

Fixed in trunk / 3.2 .

Diego Plentz
October 19, 2007, 12:40 AM

Gail, could you take a look at to see if it fix this issue too?

Gail Badner
October 19, 2007, 1:00 AM

Diego, will be fixed by the fix for this issue also. I've just closed HHH-2200. Thanks for linking the two issues.

Birger Zimmermann
November 23, 2007, 1:19 PM

Today, i mentioned that this bug seems to be present also in hibernate annotations 3.3.0.ga, with hibernate core 3.2.5.ga

In my scenario i insert many rows (> 100000) to a mysql databse which has a trigger on insert to create a md5.
I sequently commit the transaction, close and clear the session - like described for batch processing. After around 20000 inserts an out of memory exception occur. The soulution i found was to remove the @Generated annotation from my entity. Heap analysis with jhat showed the same phenomen described earlier, around 20000 open prepared statements with resultssets never closed. Because this Bug is marked for 3.2.3, 3.2.4, 3.2.4.sp1i like to tell you, it seams also present in my version combination.

Diego Plentz
December 9, 2007, 5:00 AM

Birger, it affects 3.2.3, 3.2.4, 3.2.4.sp1(and 3.2.5 too, since the fix Version/s are 3.3, 3.2.6) of hibernate core

PS: is a bug with hibernate core, not with hibernate annotations.

Assignee

Gail Badner

Reporter

Michael Werle

Fix versions

Labels

None

backPortable

None

Suitable for new contributors

None

Requires Release Note

None

Pull Request

None

backportDecision

None

Components

Affects versions

Priority

Major
Configure