Issue Type: Bug Bug
Affects Versions: 4.1.7
Assignee: Unassigned
Attachments: test-hibernate-bug.zip
Components: core
Created: 11/Oct/12 10:16 AM
Description:

In NonBatchingBatch.addToBatch() are some bugs (missing try...finally) that leaves the class in an undefined condition if the statement there fails. In addition, statements are not closed on error.

I have attached a project that shows the bug and contains a fix.

Here's my complete description (which you will also find in ShowBug.java):

/**

  • Description of the problem:
  • - we have a pre-bound session (as in OpenSessionInViewFilter) - there
  • are multiple transactions - one transaction fails - the transaction
  • manager disconnects the session (this is also true if the transaction
  • succeeds - so it should not be a problem) - according the docs
  • reconnecting should be done by transaction management - all following
  • transactions fail
  • In AbstractBatchImpl: try { doExecuteBatch(); } finally { * releaseStatements(); }
  • Statements are released within the same Transaction (ensured via
  • try...finally)
  • In NonBatchingBatch: try { [...] final int rowCount = * statement.executeUpdate(); [...] } catch ( SQLException e ) { * LOG.debug( "SQLException escaped proxy", e ); throw * sqlExceptionHelper().convert( e, "could not execute batch statement", * entry.getKey() ); } getStatements().clear();
  • Problems with this implementation: - Statements are not released here
  • - Statements are not closed if the query fails (resource leak!) -
  • statement.clearBatch() is never called (not sure if this matters. at
  • least in AbstractBatchImpl it is called) - Statements are not removed
  • from the list
  • In the next transaction (which succeeds), releaseStatements() is
  • called which fails because the proxy is not valid anymore.
  • Solution:
  • Fix the method NonBatchingBatch.addToBatch() as in attached NonBatchingBatch_fixed.java
  • Details:
  • - move all the close/release stuff outside of the loop
  • - put the loop in a "try" block
  • - in the "finally" block call super.releaseStatements()
  • - in AbstractBatchImpl make releaseStatements() protected instead of private
  • (this should really be done to avoid dupplicate code)
  • */

Project: Hibernate ORM
Priority: Blocker Blocker
Reporter: Michael Wyraz
Original Estimate: 2h
Remaining Estimate: 2h
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira