hibernate/hibernate-orm · error · UnsupportedOperationException
GaussDB only supports REF_CURSOR parameters as the first par
Error message
GaussDB only supports REF_CURSOR parameters as the first parameter
What it means
Dialect.getResultSet(CallableStatement, position) retrieves REF_CURSOR out-parameters from stored procedures. GaussDB returns refcursors through a single mechanism that only exposes the first parameter, so GaussDBDialect throws UnsupportedOperationException whenever Hibernate asks for a refcursor at any position other than 1.
Source
Thrown at hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/GaussDBDialect.java:901
@Override
public boolean supportsUnboundedLobLocatorMaterialization() {
return false;
}
@Override
public SelectItemReferenceStrategy getGroupBySelectItemReferenceStrategy() {
return SelectItemReferenceStrategy.POSITION;
}
@Override
public CallableStatementSupport getCallableStatementSupport() {
return GaussDBCallableStatementSupport.INSTANCE;
}
@Override
public ResultSet getResultSet(CallableStatement statement, int position) throws SQLException {
if ( position != 1 ) {
throw new UnsupportedOperationException( "GaussDB 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( "GaussDB only supports accessing REF_CURSOR parameters by position" );
}
@Override
public boolean qualifyIndexName() {
return false;
}
@Override
public IdentityColumnSupport getIdentityColumnSupport() {
return GaussDBIdentityColumnSupport.INSTANCE;
}View on GitHub (pinned to fad1729dce)
Solutions
- Declare exactly one REF_CURSOR parameter and make it the first parameter of the procedure call (register it at position 1)
- Return additional result sets inside the cursor (e.g. as rows tagged by type, or a refcursor set column) instead of multiple cursor parameters
- Split the multi-cursor procedure into several single-cursor procedures and call each separately
- If you need all cursors in one round trip, fetch them via a native CallableStatement using the driver-specific pattern and bypass the dialect hook
Example fix
// before (two refcursors -> second one throws on GaussDB)
StoredProcedureQuery q = em.createStoredProcedureQuery("get_data");
q.registerStoredProcedureParameter(1, void.class, ParameterMode.REF_CURSOR);
q.registerStoredProcedureParameter(2, void.class, ParameterMode.REF_CURSOR);
q.execute();
// after (single refcursor at position 1, second set via separate call)
StoredProcedureQuery q = em.createStoredProcedureQuery("get_data_a");
q.registerStoredProcedureParameter(1, void.class, ParameterMode.REF_CURSOR);
q.execute();
List<?> a = q.getResultList(); Defensive patterns
Strategy: validation
Validate before calling
// before executing, verify at most one REF_CURSOR and at position 1
long cursorCount = parameters.stream().filter(p -> p.mode == ParameterMode.REF_CURSOR).count();
if (sessionFactory.getJdbcServices().getDialect() instanceof GaussDBDialect && cursorCount > 1) {
throw new IllegalArgumentException("GaussDB supports a single REF_CURSOR as first parameter only");
} Type guard
static boolean refCursorLayoutSafe(Dialect d, List<Param> params) {
if (d instanceof GaussDBDialect) {
return params.stream().filter(p -> p.mode == ParameterMode.REF_CURSOR).count() <= 1
&& params.get(0).mode == ParameterMode.REF_CURSOR;
}
return true;
} Try / catch
try {
query.execute();
} catch (UnsupportedOperationException e) {
if (e.getMessage().contains("first parameter")) {
// split into multiple single-cursor procedure calls
} else throw e;
} Prevention
- Design procedures with one cursor result set; return composite rows instead of multiple cursors
- Always register the REF_CURSOR parameter first (position 1)
- Encapsulate procedure calls in a repository layer so per-database cursor strategies stay in one place
When it happens
Trigger: A StoredProcedureQuery/@NamedStoredProcedureQuery registered with two or more REF_CURSOR parameters (or a refcursor registered at a position after 1), then calling getResultList()/execute() - Hibernate iterates refcursor positions and the second call with position 2 throws.
Common situations: Migrating Oracle-style procedures returning multiple cursors to GaussDB; reusable procedure-call wrappers that register cursors after scalar OUT parameters; tests written against PostgreSQL getResultSet behavior being run on GaussDB.
Related errors
- GaussDB only supports accessing REF_CURSOR parameters by pos
- SingleStore does not support resultsets via stored procedure
- Unexpected error extracting REF_CURSOR parameter [{}]
- JDBC driver does not support named parameters for setArray.
- Cannot mix named parameters and REF_CURSOR parameter on Post
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/19b6dbb07252bb39.
Report an issue: GitHub.