{"record":{"id":"b11f473e104e9205","repo":"hibernate/hibernate-orm","slug":"unexpected-error-extracting-ref-cursor-parameter","errorCode":null,"errorMessage":"Unexpected error extracting REF_CURSOR parameter [{}]","messagePattern":"Unexpected error extracting REF_CURSOR parameter \\[(.+?)\\]","errorType":"exception","errorClass":"HibernateException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/engine/jdbc/cursor/internal/StandardRefCursorSupport.java","lineNumber":61,"sourceCode":"\n\t@Override\n\tpublic void registerRefCursorParameter(CallableStatement statement, String name) {\n\t\ttry {\n\t\t\tstatement.registerOutParameter( name, refCursorTypeCode() );\n\t\t}\n\t\tcatch (SQLException e) {\n\t\t\tthrow jdbcServices.getSqlExceptionHelper()\n\t\t\t\t\t.convert( e, \"Error registering REF_CURSOR parameter [\" + name + \"]\" );\n\t\t}\n\t}\n\n\t@Override\n\tpublic ResultSet getResultSet(CallableStatement statement, int position) {\n\t\ttry {\n\t\t\treturn statement.getObject( position, ResultSet.class );\n\t\t}\n\t\tcatch (Exception e) {\n\t\t\tthrow new HibernateException( \"Unexpected error extracting REF_CURSOR parameter [\" + position + \"]\", e );\n\t\t}\n\t}\n\n\t@Override\n\tpublic ResultSet getResultSet(CallableStatement statement, String name) {\n\t\ttry {\n\t\t\treturn statement.getObject( name, ResultSet.class );\n\t\t}\n\t\tcatch (Exception e) {\n\t\t\tthrow new HibernateException( \"Unexpected error extracting REF_CURSOR parameter [\" + name + \"]\", e );\n\t\t}\n\t}\n\n\t/**\n\t * Does this JDBC metadata indicate that the driver defines REF_CURSOR support?\n\t *\n\t * @param meta The JDBC metadata\n\t *","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/engine/jdbc/cursor/internal/StandardRefCursorSupport.java#L43-L79","documentation":"StandardRefCursorSupport.getResultSet(CallableStatement, int) extracts a REF_CURSOR out-parameter via the JDBC 4.1 call statement.getObject(position, ResultSet.class). Any failure thrown by the driver - unsupported typed extraction, wrong parameter position, the parameter not actually being a cursor - is caught as Exception and rewrapped as HibernateException with the position appended, preserving the original cause.","triggerScenarios":"ProcedureCall / StoredProcedureQuery with a registered ref-cursor parameter where getObject(position, ResultSet.class) throws: the position does not point at a cursor parameter, the driver implements JDBC 4.1 partially (AbstractMethodError/SQLFeatureNotSupportedException), or the cursor was already consumed.","commonSituations":"Calling stored procedures returning cursors (PostgreSQL functions, Oracle SYS_REFCURSOR) with older or limited JDBC drivers; parameter index off-by-one after reordering procedure parameters; drivers whose ResultSet.class extraction needs the cursor to be the next output.","solutions":["Verify the position used when registering the ref-cursor parameter matches the procedure's actual parameter order","Upgrade the JDBC driver to one that fully supports getObject(int, Class) ref-cursor extraction","As a workaround, retrieve the cursor untyped - Object out = statement.getObject(position) - and cast to ResultSet","Check the nested cause (SQLException/AbstractMethodError) to distinguish driver limitation from wrong position"],"exampleFix":"// before\nProcedureCall call = session.createStoredProcedureCall(\"fetch_users\");\ncall.registerParameter(2, void.class, ParameterMode.REF_CURSOR);\nResultSet rs = call.getOutputs().getOutputParameterValue(2); // wrong position / driver\n\n// after: position matches the procedure signature and driver supports JDBC 4.1\nPostgresCallableStatement pcs = ...; // or upgrade driver\nResultSet rs = (ResultSet) ((CallableStatement) stmt).getObject(2); // untyped fallback","handlingStrategy":"try-catch","validationCode":"// check driver capability before relying on typed ref-cursor extraction\nDatabaseMetaData meta = connection.getMetaData();\nif ( !StandardRefCursorSupport.supportsRefCursors(meta) ) {\n    // fall back to untyped extraction or positional handling\n}","typeGuard":null,"tryCatchPattern":"try {\n    return stmt.getObject(position, ResultSet.class);\n} catch (Exception e) {\n    Object raw = stmt.getObject(position); // untyped fallback for weak drivers\n    return (ResultSet) raw;\n}","preventionTips":["Register ref-cursor parameters with the exact position from the procedure signature and cover it with an integration test against the real DB","Keep the JDBC driver current; typed getObject(int, Class) support is a JDBC 4.1 requirement"],"tags":["hibernate","jdbc","ref-cursor","stored-procedure","callable-statement"],"backgroundTag":"ref-cursor-extraction-failed","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}