hibernate/hibernate-orm · error · UnsupportedOperationException
PostgreSQL only supports REF_CURSOR parameters as the first
Error message
PostgreSQL only supports REF_CURSOR parameters as the first parameter
What it means
PostgreSQL's server/JDBC combination only materializes a refcursor returned as the first OUT parameter of a callable statement. PostgreSQLLegacyDialect.getResultSet(CallableStatement, position) therefore requires position == 1 and throws UnsupportedOperationException for any other position when Hibernate extracts REF_CURSOR output parameters from a StoredProcedureQuery/ProcedureCall.
Source
Thrown at hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgreSQLLegacyDialect.java:1163
public boolean supportsUnboundedLobLocatorMaterialization() {
return false;
}
@Override
public SelectItemReferenceStrategy getGroupBySelectItemReferenceStrategy() {
return SelectItemReferenceStrategy.POSITION;
}
@Override
public CallableStatementSupport getCallableStatementSupport() {
return getVersion().isSameOrAfter( 11 ) ? PostgreSQLCallableStatementSupport.INSTANCE : PostgreSQLCallableStatementSupport.V10_INSTANCE;
}
@Override
public ResultSet getResultSet(CallableStatement statement, int position) throws SQLException {
if ( position != 1 ) {
throw new UnsupportedOperationException( "PostgreSQL only supports REF_CURSOR parameters as the first parameter" );
}
return (ResultSet) statement.getObject( 1 );
}
@Override
public ResultSet getResultSet(CallableStatement statement, String name) throws SQLException {
throw new UnsupportedOperationException( "PostgreSQL only supports accessing REF_CURSOR parameters by position" );
}
@Override
public boolean qualifyIndexName() {
return false;
}
@Override
public IdentityColumnSupport getIdentityColumnSupport() {
return PostgreSQLIdentityColumnSupport.INSTANCE;
}View on GitHub (pinned to fad1729dce)
Solutions
- Redesign the function to return a single refcursor in the first parameter
- Return SETOF rows instead of a refcursor and call it as 'select * from func()'
- Fetch additional cursors manually: (ResultSet) callableStatement.getObject(n) outside Hibernate
- Access only output position 1 through Hibernate
Example fix
-- before create function read_orders(out c1 refcursor, out c2 refcursor) ... // Java: outputs.getOutputByPosition(2).asResultSet() -> throws -- after create function read_orders() returns setof orders ... List<Order> l = em.createNativeQuery( "select * from read_orders()", Order.class ).getResultList();
Defensive patterns
Strategy: validation
Validate before calling
// PostgreSQL: Hibernate can only retrieve a REF_CURSOR at position 1
int cursorPosition = 1;
if ( cursorPosition != 1 ) {
throw new IllegalArgumentException(
"Fetch this cursor manually via callableStatement.getObject(position)" );
}
StoredProcedureQuery q = em.createStoredProcedureQuery( "read_orders" );
q.registerStoredProcedureParameter( 1, void.class, ParameterMode.REF_CURSOR ); Try / catch
try {
ResultSet rs = dialect.getResultSet( stmt, position );
}
catch ( UnsupportedOperationException e ) {
// PostgreSQL: fall back to raw JDBC retrieval
ResultSet rs = (ResultSet) stmt.getObject( position );
} Prevention
- Keep exactly one refcursor as the first OUT parameter of stored functions
- Prefer set-returning functions queried with select over cursors
- Smoke-test stored procedures against the target database in CI
When it happens
Trigger: A PL/pgSQL function with multiple refcursor OUT parameters, then asking Hibernate for the result set at position 2 or higher (iterating outputs / hasMoreResults-style access); StoredProcedureQuery on PostgreSQL registering more than one cursor output.
Common situations: Porting SQL Server/Oracle procedures that return several cursors per call; expecting PostgreSQL to behave like Oracle with multiple cursors; report screens fed by one procedure returning several result sets.
Related errors
- PostgreSQL only supports accessing REF_CURSOR parameters by
- Unexpected error extracting REF_CURSOR parameter [{}]
- Cannot mix named parameters and REF_CURSOR parameter on Post
- PostgreSQL supports only one REF_CURSOR parameter, but multi
- Dialect [" + dialect.getClass().getName() + "] not known to
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/5dc1eafd6018c2f0.
Report an issue: GitHub.