{"record":{"id":"ef0997ea29c0b45d","repo":"hibernate/hibernate-orm","slug":"procedurecall-cannot-be-treated-as-selectionquery","errorCode":null,"errorMessage":"ProcedureCall cannot be treated as SelectionQuery","messagePattern":"ProcedureCall cannot be treated as SelectionQuery","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/procedure/internal/ProcedureCallImpl.java","lineNumber":258,"sourceCode":"\t@Nonnull\n\tpublic String getProcedureName() {\n\t\treturn procedureName;\n\t}\n\n\t@Override\n\t@Nullable\n\tpublic String getQueryString() {\n\t\treturn \"ProcedureCall::\" + procedureName;\n\t}\n\n\n\t// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\t// Casts\n\n\t@Override\n\t@Nonnull\n\tpublic SelectionQueryImplementor<R> asSelectionQuery() {\n\t\tthrow new IllegalArgumentException( \"ProcedureCall cannot be treated as SelectionQuery\" );\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic <X> SelectionQueryImplementor<X> asSelectionQuery(Class<X> type) {\n\t\tthrow new IllegalArgumentException( \"ProcedureCall cannot be treated as SelectionQuery\" );\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic <X> SelectionQueryImplementor<X> asSelectionQuery(EntityGraph<X> entityGraph) {\n\t\tthrow new IllegalArgumentException( \"ProcedureCall cannot be treated as SelectionQuery\" );\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic <X> SelectionQueryImplementor<X> withResultSetMapping(@Nonnull jakarta.persistence.sql.ResultSetMapping<X> mapping) {\n\t\tthrow new IllegalArgumentException( \"ProcedureCall cannot be treated as SelectionQuery\" );","sourceCodeStart":240,"sourceCodeEnd":276,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/procedure/internal/ProcedureCallImpl.java#L240-L276","documentation":"Hibernate 6.5+ replaces blind Query casts with explicit asSelectionQuery()/asMutationQuery() conversions on the common query contract. ProcedureCallImpl implements that contract, but a stored-procedure call is not a SelectionQuery (its results flow through getOutputs()/ProcedureCall result APIs), so the untyped asSelectionQuery() throws IllegalArgumentException.","triggerScenarios":"Calling asSelectionQuery() on a ProcedureCall returned by session.createStoredProcedureQuery(...)/getNamedProcedureCall(...); generic helper code that normalizes every jakarta.persistence.Query to SelectionQuery.","commonSituations":"Migrating pre-6.5 code that did (SelectionQuery<R>) query casts to the new conversion API; shared repository utilities accepting only SelectionQuery; Spring Data-style fragments that upcast every query.","solutions":["Branch on type before converting: if (query instanceof ProcedureCall) use execute()/getResultList() directly.","Overload helpers for ProcedureCall/StoredProcedureQuery instead of normalizing everything to SelectionQuery.","For typed results, supply result mappings at creation time (createStoredProcedureQuery(name, mapping...))."],"exampleFix":"// before\nSelectionQuery<Order> q = (SelectionQuery<Order>) session\n        .createStoredProcedureQuery(\"find_orders\")\n        .asSelectionQuery();\n\n// after\nProcedureCall call = session.getNamedProcedureCall(\"find_orders\");\nList<Order> orders = call.getResultList();","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"static boolean isProcedureCall(jakarta.persistence.Query q) {\n    return q instanceof org.hibernate.procedure.ProcedureCall;\n}","tryCatchPattern":"try {\n    SelectionQuery<R> sq = query.asSelectionQuery();\n} catch (IllegalArgumentException e) {\n    // query was a ProcedureCall; fall back to the procedure result API\n    List<R> rows = (List<R>) ((ProcedureCall<?>) query).getResultList();\n}","preventionTips":["instanceof-check ProcedureCall before asSelectionQuery/asMutationQuery conversions.","Overload shared helpers per query type instead of normalizing everything to SelectionQuery.","During 6.5+ migrations, replace old (SelectionQuery) casts with a guarded conversion helper."],"tags":["hibernate","stored-procedure","selection-query","query-cast","api-migration"],"backgroundTag":"query-type-mismatch","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}