hibernate/hibernate-orm · error · QueryException

Dialect [" + procedureCall.getSession().getJdbcServices().ge

Error message

Dialect [" + procedureCall.getSession().getJdbcServices().getJdbcEnvironment().getDialect().getClass().getName() + "] not known to support REF_CURSOR parameters

What it means

SybaseCallableStatementSupport renders the call string parameter-by-parameter and throws QueryException the instant it encounters a ParameterMode.REF_CURSOR registration, resolving the dialect name from procedureCall.getSession().getJdbcServices().getJdbcEnvironment().getDialect(). Sybase ASE has no REF_CURSOR parameter type; procedures there return result sets implicitly.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/procedure/internal/SybaseCallableStatementSupport.java:75

					.append( FUNCTION_SYNTAX_START );
		}
		else {
			offset = 1;
			buffer = new StringBuilder( CALL_SYNTAX_START.length() + CALL_SYNTAX_END.length() + procedureName.length() + paramStringSizeEstimate )
					.append( CALL_SYNTAX_START );
		}

		buffer.append( procedureName );

		if ( registrations.isEmpty() ) {
			buffer.append( '(' );
		}
		else {
			char sep = '(';
			for ( int i = 0; i < registrations.size(); i++ ) {
				final ProcedureParameterImplementor<?> parameter = registrations.get( i );
				if ( parameter.getMode() == ParameterMode.REF_CURSOR ) {
					throw new QueryException( "Dialect [" + procedureCall.getSession().getJdbcServices().getJdbcEnvironment().getDialect().getClass().getName() + "] not known to support REF_CURSOR parameters" );
				}
				buffer.append( sep );
				final JdbcCallParameterRegistration registration = parameter.toJdbcParameterRegistration(
						i + offset,
						procedureCall
				);
				final SharedSessionContractImplementor session = procedureCall.getSession();
				if (  parameter.getName() != null
						&& session.getJdbcServices().getExtractedMetaDataSupport().supportsNamedParameters()
						&& session.getFactory().getSessionFactoryOptions().isPassProcedureParameterNames()  ) {
					buffer.append("@").append( parameter.getName() ).append( " = ?" );
				}
				else {
					buffer.append( "?" );
				}
				sep = ',';
				builder.addParameterRegistration( registration );
			}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Drop the REF_CURSOR registration on Sybase and read the implicit result sets via getResults()/getResultList()
  2. Branch on dialect.supportsRefCursors() (it is false for Sybase) so Sybase uses a cursorless code path
  3. Wrap the Sybase procedure so it SELECTs rows back instead of opening a cursor parameter

Example fix

// before
call.registerParameter(1, void.class, ParameterMode.REF_CURSOR); // Sybase: unsupported

// after
ProcedureOutputs outputs = call.execute();
List<?> orders = outputs.getResultList(); // implicit result set on Sybase
Defensive patterns

Strategy: validation

Validate before calling

Dialect dialect = session.getJdbcServices().getJdbcEnvironment().getDialect();
boolean sybasePath = !dialect.supportsRefCursors(); // Sybase ASE: false
// if (sybasePath) do not register ParameterMode.REF_CURSOR at all

Try / catch

try {
    call.execute();
} catch (org.hibernate.QueryException e) {
    if (e.getMessage().contains("REF_CURSOR")) {
        // Sybase path: remove REF_CURSOR registration, read result sets via getResults()
    }
}

Prevention

When it happens

Trigger: Any ParameterMode.REF_CURSOR registration on a session whose dialect resolves to a Sybase dialect — thrown while building the {call ...} string, before execution. The name check runs per registration inside the rendering loop.

Common situations: Shared stored-procedure code run against multiple databases where one target is Sybase ASE; migrations onto Sybase; test matrices where one node uses jConnect/jTDS with Sybase dialect resolution.

Related errors


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