{"record":{"id":"77d9b40cbf7739ac","repo":"hibernate/hibernate-orm","slug":"error-extracting-procedure-output-parameter-value","errorCode":null,"errorMessage":"Error extracting procedure output parameter value [\" + parameter + \"]","messagePattern":"Error extracting procedure output parameter value \\[\" \\+ parameter \\+ \"\\]","errorType":"exception","errorClass":"ExecutionException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/procedure/internal/OutputsImpl.java","lineNumber":144,"sourceCode":"\t\ttry {\n\t\t\tif ( registration.getParameterMode() == ParameterMode.REF_CURSOR ) {\n\t\t\t\t//noinspection unchecked\n\t\t\t\treturn (T) registration.getRefCursorExtractor().extractResultSet(\n\t\t\t\t\t\tjdbcStatement,\n\t\t\t\t\t\tprocedureCall.getSession()\n\t\t\t\t);\n\t\t\t}\n\t\t\telse {\n\t\t\t\t//noinspection unchecked\n\t\t\t\treturn (T) registration.getParameterExtractor().extractValue(\n\t\t\t\t\t\tjdbcStatement,\n\t\t\t\t\t\tparameter.getPosition() == null,\n\t\t\t\t\t\tprocedureCall.getSession()\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tcatch (Exception e) {\n\t\t\tthrow new ExecutionException(\n\t\t\t\t\t\"Error extracting procedure output parameter value [\" + parameter + \"]\",\n\t\t\t\t\te\n\t\t\t);\n\t\t}\n\t}\n\n\t@Override\n\tpublic Object getOutputParameterValue(String name) {\n\t\treturn getOutputParameterValue( procedureCall.getParameterMetadata().getQueryParameter( name ) );\n\t}\n\n\t@Override\n\tpublic Object getOutputParameterValue(int position) {\n\t\treturn getOutputParameterValue( procedureCall.getParameterMetadata().getQueryParameter( position ) );\n\t}\n\n\n\t@Override","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/procedure/internal/OutputsImpl.java#L126-L162","documentation":"This ExecutionException is a wrapper: after execution, Hibernate asked the JDBC CallableStatement for the output value (via ParameterExtractor or RefCursorExtractor) and the driver threw. The real reason is in the cause — typical cases are reading an output parameter before all result sets/update counts are consumed, a Java type registered that the SQL type won't coerce to, or REF_CURSOR extraction when the statement does not supply a result set.","triggerScenarios":"getOutputParameterValue(...) before execute() completes or before draining returned result sets; registering e.g. String.class for a NUMBER OUT parameter; extracting a REF_CURSOR after the statement/cursor was closed; calling extraction twice on drivers that invalidate the value.","commonSituations":"PostgreSQL/Oracle ordering rules (output values valid only after results are drained); type guesses during schema evolution (column widened to NUMBER); long-running procedures where the driver times out and the CallableStatement is unusable.","solutions":["Call execute() first and consume all results (hasMoreResults()/getResultList()/getUpdateCount loop) before reading output parameters.","Unwrap the ExecutionException's cause and fix the registered Java type to match the SQL OUT type.","For REF_CURSOR parameters, register java.sql.ResultSet (ParameterMode.REF_CURSOR) and read it while the statement is open."],"exampleFix":"// before\nproc.execute();\nObject v = proc.getOutputParameterValue(\"status\"); // driver fails mid-extraction\n\n// after\nproc.execute();\nwhile (proc.hasMoreResults()) { proc.getResultList(); } // drain results first\nObject v = proc.getOutputParameterValue(\"status\");","handlingStrategy":"try-catch","validationCode":"// ensure execute() has run and results are drained before extraction\nboolean executed = proc.execute();\nwhile ( proc.hasMoreResults() ) {\n    proc.getResultList();\n}\nif ( proc.getUpdateCount() != -1 ) { /* update count consumed */ }\nObject value = proc.getOutputParameterValue( name );","typeGuard":null,"tryCatchPattern":"try {\n    Object v = proc.getOutputParameterValue( name );\n} catch (org.hibernate.ExecutionException e) {\n    Throwable cause = e.getCause(); // the actual SQLException / driver failure\n    log.warn( \"output parameter [{}] extraction failed: {}\", name, cause.getMessage() );\n    throw new IllegalStateException( \"procedure \" + proc.getProcedureName() + \" output failed\", cause );\n}","preventionTips":["Always call execute() and drain result sets before reading output parameters.","Register the exact Java type matching the SQL OUT type.","Log the cause chain, not the wrapper message, when diagnosing extraction failures."],"tags":["hibernate","stored-procedure","jdbc","output-parameter","exception-wrapping"],"backgroundTag":"output-parameter-extraction-failed","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}