{"record":{"id":"18f18bc5f1528605","repo":"hibernate/hibernate-orm","slug":"postgresql-only-supports-accessing-ref-cursor-para","errorCode":null,"errorMessage":"PostgreSQL only supports accessing REF_CURSOR parameters by position","messagePattern":"PostgreSQL only supports accessing REF_CURSOR parameters by position","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgreSQLLegacyDialect.java","lineNumber":1170,"sourceCode":"\t}\n\n\n\t@Override\n\tpublic CallableStatementSupport getCallableStatementSupport() {\n\t\treturn getVersion().isSameOrAfter( 11 ) ? PostgreSQLCallableStatementSupport.INSTANCE : PostgreSQLCallableStatementSupport.V10_INSTANCE;\n\t}\n\n\t@Override\n\tpublic ResultSet getResultSet(CallableStatement statement, int position) throws SQLException {\n\t\tif ( position != 1 ) {\n\t\t\tthrow new UnsupportedOperationException( \"PostgreSQL only supports REF_CURSOR parameters as the first parameter\" );\n\t\t}\n\t\treturn (ResultSet) statement.getObject( 1 );\n\t}\n\n\t@Override\n\tpublic ResultSet getResultSet(CallableStatement statement, String name) throws SQLException {\n\t\tthrow new UnsupportedOperationException( \"PostgreSQL only supports accessing REF_CURSOR parameters by position\" );\n\t}\n\n\t@Override\n\tpublic boolean qualifyIndexName() {\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic IdentityColumnSupport getIdentityColumnSupport() {\n\t\treturn PostgreSQLIdentityColumnSupport.INSTANCE;\n\t}\n\n\t@Override\n\tpublic NationalizationSupport getNationalizationSupport() {\n\t\treturn NationalizationSupport.IMPLICIT;\n\t}\n\n\t@Override","sourceCodeStart":1152,"sourceCodeEnd":1188,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgreSQLLegacyDialect.java#L1152-L1188","documentation":"PostgreSQL JDBC has no mechanism to resolve a refcursor by name, so PostgreSQLLegacyDialect.getResultSet(CallableStatement, String name) unconditionally throws UnsupportedOperationException. Hibernate reaches it when a REF_CURSOR output parameter is retrieved by name instead of position (for example ProcedureOutputs.getOutput(name).asResultSet()).","triggerScenarios":"Named retrieval of a REF_CURSOR output parameter from a ProcedureCall/StoredProcedureQuery on PostgreSQL; frameworks that address stored-procedure outputs by parameter name.","commonSituations":"Code ported from Oracle where named-cursor access is idiomatic; migrations of legacy DAO layers that name every output parameter.","solutions":["Retrieve the cursor by position 1 instead of by name","Switch to a set-returning function called via select","Avoid REF_CURSOR parameters entirely on PostgreSQL"],"exampleFix":"// before\nProcedureOutputs outputs = procCall.getOutputs();\nResultSet rs = outputs.getOutput( \"result_cursor\" ).asResultSet(); // -> throws\n\n// after\nResultSet rs = outputs.getOutputByPosition( 1 ).asResultSet();","handlingStrategy":"fallback","validationCode":"// never address PostgreSQL REF_CURSOR outputs by name\nif ( outputName != null && dialect instanceof PostgreSQLLegacyDialect ) {\n    outputName = null; // use position 1 instead\n}","typeGuard":null,"tryCatchPattern":"try {\n    return outputs.getOutput( name ).asResultSet();\n}\ncatch ( UnsupportedOperationException e ) {\n    // PostgreSQL has no by-name cursor access: fall back to positional retrieval\n    return outputs.getOutputByPosition( 1 ).asResultSet();\n}","preventionTips":["Address stored-procedure outputs by position on PostgreSQL","Prefer set-returning functions over refcursor parameters","Abstract cursor access behind a small DAO so the retrieval mode is dialect-controlled"],"tags":["postgresql","stored-procedure","ref-cursor","jdbc"],"backgroundTag":"stored-procedure-ref-cursor","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}