|
JDBC Statement is not closed when exception appeared during query execution, JPA native query on Oracle v11 database.
If run statement in cycle
entityManager.createNativeQuery("Select 1 from NotExistedTable").getResultList();
On iteration 300 error appeared: ORA-01000: maximum open cursors exceeded
I can provide sample project if required, but issue is obvious by code review, method "org.hibernate.loader.Loader.doQuery(SessionImplementor, QueryParameters, boolean, ResultTransformer)" Exception appeared on line with "executeQueryStatement", this block is not covered by "finally".
private List doQuery(
final SessionImplementor session,
final QueryParameters queryParameters,
final boolean returnProxies,
final ResultTransformer forcedResultTransformer) throws SQLException, HibernateException {
final RowSelection selection = queryParameters.getRowSelection();
final int maxRows = LimitHelper.hasMaxRows( selection ) ?
selection.getMaxRows() :
Integer.MAX_VALUE;
final List<AfterLoadAction> afterLoadActions = new ArrayList<AfterLoadAction>();
final SqlStatementWrapper wrapper = executeQueryStatement( queryParameters, false, afterLoadActions, session );
final ResultSet rs = wrapper.getResultSet();
final Statement st = wrapper.getStatement();
try {
return processResultSet( rs, queryParameters, session, returnProxies, forcedResultTransformer, maxRows, afterLoadActions );
}
finally {
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
}
}
Also if enable logging, normal execution contains "JdbcCoordinatorImpl: Closing prepared statement", and absent in execution with exception.
INFO org.hibernate.issues.NativeQueryIssueTest: Iteration: 319
DEBUG org.hibernate.SQL: Select 1 from Dual
TRACE org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl: Registering statement [oracle.jdbc.driver.OraclePreparedStatementWrapper@34645867]
TRACE org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl: Registering last query statement [oracle.jdbc.driver.OraclePreparedStatementWrapper@34645867]
TRACE org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl: Registering result set [oracle.jdbc.driver.ForwardOnlyResultSet@2484f433]
TRACE org.hibernate.type.descriptor.sql.BasicExtractor: extracted value ([1] : [NUMERIC]) - [1]
TRACE org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl: Releasing statement [oracle.jdbc.driver.OraclePreparedStatementWrapper@34645867]
TRACE org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl: Closing result set [oracle.jdbc.driver.ForwardOnlyResultSet@2484f433]
TRACE org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl: Closing prepared statement [oracle.jdbc.driver.OraclePreparedStatementWrapper@34645867]
TRACE org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl: Starting after statement execution processing [ON_CLOSE]
INFO org.hibernate.issues.NativeQueryIssueTest: Iteration: 300
DEBUG org.hibernate.SQL: Select 1 from NotExistedTable
TRACE org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl: Registering statement [oracle.jdbc.driver.OraclePreparedStatementWrapper@3234f74e]
TRACE org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl: Registering last query statement [oracle.jdbc.driver.OraclePreparedStatementWrapper@3234f74e]
WARN org.hibernate.engine.jdbc.spi.SqlExceptionHelper: SQL Error: 1000, SQLState: 72000
ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper: ORA-01000: maximum open cursors exceeded
Solution: "executeQueryStatement" have to be covered with "finally".
|