We're updating the issue view to help you get more done. 

Compatibility improvement suggestion for org.hibernate.engine.jdbc.internal.ResultSetReturnImpl


The fix implemented for issue in org.hibernate.engine.jdbc.internal.ResultSetReturnImpl performs an instanceof check on the statement object to determine if the current statement is an instance of CallableStatement. This presents a potential problem if a framework wraps a statement object in either a proxy or a concrete class that implements both PreparedStatement and CallableStatement.

This can result in wrapped/proxied PreparedStatement objects being incorrectly identified as CallableStatement instances with the end result often being a ClassCastException, AbstractMethodError, or NoSuchMethodException error in the wrapper or proxy.

Since JDK 6 is now a minimum requirement it seems like a more compatible fix would have been to call java.sql.Wrapper.isWrapperFor(CallableStatement.class) method on the statement object to determine the instance type instead of using the instanceof keyword. While I'm not stating that the implemented fix is technically wrong, I believe the use of Wrapper.isWrapperFor would promote improved compatibility across the greatest range of pooling frameworks, JDBC drivers, etc.

Improvement Suggestion:


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 public ResultSet extract(PreparedStatement statement) { // IMPL NOTE : SQL logged by caller if (isTypeOf(statement, CallableStatement.class)) { // We actually need to extract from Callable statement. Although // this seems needless, Oracle can return an // OracleCallableStatementWrapper that finds its way to this method, // rather than extract(CallableStatement). See HHH-8022. final CallableStatement callableStatement = (CallableStatement) statement; return extract( callableStatement ); } try { final ResultSet rs; try { jdbcCoordinator.getTransactionCoordinator().getTransactionContext().startStatementExecution(); rs = statement.executeQuery(); } finally { jdbcCoordinator.getTransactionCoordinator().getTransactionContext().endStatementExecution(); } postExtract( rs, statement ); return rs; } catch (SQLException e) { throw sqlExceptionHelper.convert( e, "could not extract ResultSet" ); } } private boolean isTypeOf(final Statement statement, final Class<? extends Statement> type) { boolean matches; try { // Verify if the statement either implements the interface directly // or is a wrapper for the specified type via the JDBC API matches = statement.isWrapperFor(type); } catch (SQLException e) { // If the wrapper check fails for some reason, fall back to assignable class verification matches = type.isAssignableFrom(statement.getClass()); } return matches; }


Hibernate Core 4.3.5, Oracle 11g



Brett Meyer


Joel Bagley

Fix versions




Suitable for new contributors


Requires Release Note





Affects versions