hibernate/hibernate-orm · error · HibernateException

Unexpected error extracting REF_CURSOR parameter [{}]

Error message

Unexpected error extracting REF_CURSOR parameter [{}]

What it means

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.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/engine/jdbc/cursor/internal/StandardRefCursorSupport.java:61

	@Override
	public void registerRefCursorParameter(CallableStatement statement, String name) {
		try {
			statement.registerOutParameter( name, refCursorTypeCode() );
		}
		catch (SQLException e) {
			throw jdbcServices.getSqlExceptionHelper()
					.convert( e, "Error registering REF_CURSOR parameter [" + name + "]" );
		}
	}

	@Override
	public ResultSet getResultSet(CallableStatement statement, int position) {
		try {
			return statement.getObject( position, ResultSet.class );
		}
		catch (Exception e) {
			throw new HibernateException( "Unexpected error extracting REF_CURSOR parameter [" + position + "]", e );
		}
	}

	@Override
	public ResultSet getResultSet(CallableStatement statement, String name) {
		try {
			return statement.getObject( name, ResultSet.class );
		}
		catch (Exception e) {
			throw new HibernateException( "Unexpected error extracting REF_CURSOR parameter [" + name + "]", e );
		}
	}

	/**
	 * Does this JDBC metadata indicate that the driver defines REF_CURSOR support?
	 *
	 * @param meta The JDBC metadata
	 *

View on GitHub (pinned to fad1729dce)

Solutions

  1. Verify the position used when registering the ref-cursor parameter matches the procedure's actual parameter order
  2. Upgrade the JDBC driver to one that fully supports getObject(int, Class) ref-cursor extraction
  3. As a workaround, retrieve the cursor untyped - Object out = statement.getObject(position) - and cast to ResultSet
  4. Check the nested cause (SQLException/AbstractMethodError) to distinguish driver limitation from wrong position

Example fix

// before
ProcedureCall call = session.createStoredProcedureCall("fetch_users");
call.registerParameter(2, void.class, ParameterMode.REF_CURSOR);
ResultSet rs = call.getOutputs().getOutputParameterValue(2); // wrong position / driver

// after: position matches the procedure signature and driver supports JDBC 4.1
PostgresCallableStatement pcs = ...; // or upgrade driver
ResultSet rs = (ResultSet) ((CallableStatement) stmt).getObject(2); // untyped fallback
Defensive patterns

Strategy: try-catch

Validate before calling

// check driver capability before relying on typed ref-cursor extraction
DatabaseMetaData meta = connection.getMetaData();
if ( !StandardRefCursorSupport.supportsRefCursors(meta) ) {
    // fall back to untyped extraction or positional handling
}

Try / catch

try {
    return stmt.getObject(position, ResultSet.class);
} catch (Exception e) {
    Object raw = stmt.getObject(position); // untyped fallback for weak drivers
    return (ResultSet) raw;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/b11f473e104e9205. Report an issue: GitHub.