{"record":{"id":"0cbc2ef15435fc8f","repo":"hibernate/hibernate-orm","slug":"procedurecall-cannot-be-treated-as-a-selection-que","errorCode":null,"errorMessage":"ProcedureCall cannot be treated as a selection query","messagePattern":"ProcedureCall cannot be treated as a selection query","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/procedure/internal/NamedCallableQueryMementoImpl.java","lineNumber":170,"sourceCode":"\t\treturn makeProcedureCall( session );\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic MutationQueryImplementor<Object> toMutationQuery(@Nonnull SharedSessionContractImplementor session) {\n\t\tthrow new UnsupportedOperationException( \"ProcedureCall cannot be treated as a mutation query\" );\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic <T> MutationQueryImplementor<T> toMutationQuery(@Nonnull SharedSessionContractImplementor session, @Nullable Class<T> targetType) {\n\t\tthrow new UnsupportedOperationException( \"ProcedureCall cannot be treated as a mutation query\" );\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic SelectionQueryImplementor<Object> toSelectionQuery(@Nonnull SharedSessionContractImplementor session) {\n\t\tthrow new UnsupportedOperationException( \"ProcedureCall cannot be treated as a selection query\" );\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic <T> SelectionQueryImplementor<T> toSelectionQuery(@Nonnull SharedSessionContractImplementor session, @Nullable Class<T> javaType) {\n\t\tthrow new UnsupportedOperationException( \"ProcedureCall cannot be treated as a selection query\" );\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic NamedQueryMemento<Object> makeCopy(@Nonnull String name) {\n\t\treturn new NamedCallableQueryMementoImpl( name, this );\n\t}\n\n\t@Override\n\tpublic void validate(@Nonnull QueryEngine queryEngine) {\n\t\t// anything to do?\n\t}","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/procedure/internal/NamedCallableQueryMementoImpl.java#L152-L188","documentation":"When a named query is resolved with selection semantics (session.createNamedSelectionQuery(name, type), see AbstractSharedSessionContract), Hibernate asks the stored memento to convert itself via toSelectionQuery(session). NamedCallableQueryMementoImpl, the memento for @NamedStoredProcedureQuery registrations, cannot become a SelectionQueryImplementor because stored-procedure results are consumed through ProcedureCall.getOutputs(), so it throws UnsupportedOperationException.","triggerScenarios":"Calling session.createNamedSelectionQuery(\"procName\", SomeClass.class) where procName is a @NamedStoredProcedureQuery; any code that resolves named queries strictly through the SelectionQuery contract.","commonSituations":"Post-6.5 migrations that replaced createNamedQuery casts with createSelectionQuery; read-only service layers that normalize every named query to SelectionQuery; test fixtures that iterate all named queries through one creation API.","solutions":["Create the procedure query via em.createNamedStoredProcedureQuery(name) or session.getNamedProcedureCall(name) and consume results with getResultList()/getOutputs().","Use em.createNamedQuery(name, SomeClass.class), which routes the callable memento to makeProcedureCall instead of toSelectionQuery.","If the procedure only returns data, consider a native selection query over a table function (select * from f(...)) instead."],"exampleFix":"// before\nSelectionQuery<AuditRow> q = session.createNamedSelectionQuery(\"audit_rows_proc\", AuditRow.class);\n\n// after\nProcedureCall call = session.getNamedProcedureCall(\"audit_rows_proc\");\nList<AuditRow> rows = call.getResultList();","handlingStrategy":"validation","validationCode":"final NamedQueryMemento<?> memento = ((SessionFactoryImplementor) sessionFactory)\n        .getQueryEngine().getNamedObjectRepository()\n        .getQueryMementoByName( queryName, false );\nif ( memento instanceof NamedCallableQueryMemento ) {\n    ProcedureCall<?> call = session.getNamedProcedureCall( queryName ); // selection path\n    List<?> results = call.getResultList();\n} else {\n    SelectionQuery<?> q = session.createNamedSelectionQuery( queryName, type );\n}","typeGuard":"static boolean isCallableNamedQuery(String name, SessionFactoryImplementor sf) {\n    return sf.getQueryEngine().getNamedObjectRepository()\n            .getQueryMementoByName( name, false )\n            instanceof NamedCallableQueryMemento;\n}","tryCatchPattern":"try {\n    SelectionQuery<R> q = session.createNamedSelectionQuery( name, type );\n} catch (UnsupportedOperationException e) {\n    List<R> rows = (List<R>) session.getNamedProcedureCall( name ).getResultList();\n}","preventionTips":["Use createNamedQuery(name, type) when a name may resolve to either HQL or a procedure.","Reserve createNamedSelectionQuery for names you know are HQL/native selections.","Centralize named-query creation in one factory method that knows each name's kind."],"tags":["hibernate","stored-procedure","selection-query","named-query"],"backgroundTag":"query-type-mismatch","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}