{"record":{"id":"4250f540fae94e34","repo":"hibernate/hibernate-orm","slug":"not-supported-4250f5","errorCode":null,"errorMessage":"Not supported","messagePattern":"Not supported","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/procedure/internal/ProcedureCallImpl.java","lineNumber":362,"sourceCode":"\t\tthrow new UnsupportedOperationException( \"Fetch profiles not supported for ProcedureCall\" );\n\t}\n\n\t@Override @Deprecated\n\t@SuppressWarnings(\"removal\")\n\t@Nonnull\n\tpublic Query<R> disableFetchProfile(@Nonnull String profileName) {\n\t\tthrow new UnsupportedOperationException( \"Fetch profiles not supported for ProcedureCall\" );\n\t}\n\n\t@Override\n\tpublic boolean isQueryPlanCacheable() {\n\t\treturn false;\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic ProcedureCallImplementor<R> setQueryPlanCacheable(boolean queryPlanCacheable) {\n\t\tthrow new UnsupportedOperationException( \"Not supported\" );\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic ProcedureCallImplementor<R> setTimeout(@Nullable Integer timeout) {\n\t\tcheckNotClosed();\n\t\tif ( timeout == null ) {\n\t\t\ttimeout = -1;\n\t\t}\n\t\tsuper.setTimeout( timeout );\n\t\treturn this;\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic ProcedureCallImplementor<R> setTimeout(int timeout) {\n\t\tcheckNotClosed();\n\t\tsuper.setTimeout( timeout );","sourceCodeStart":344,"sourceCodeEnd":380,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/procedure/internal/ProcedureCallImpl.java#L344-L380","documentation":"ProcedureCallImpl hard-codes isQueryPlanCacheable() to false and throws UnsupportedOperationException from setQueryPlanCacheable(boolean). Stored-procedure calls have no translated plan to cache — each execution builds a JdbcCall from the current parameter registrations — so plan caching is intentionally unavailable on this query type rather than silently ignored.","triggerScenarios":"Calling setQueryPlanCacheable(true) (or false) on a ProcedureCall; bulk tuning code that iterates queries and flips cacheability everywhere.","commonSituations":"Query-plan-cache investigation/tuning passes applied uniformly to all queries; framework code copying cacheable settings from one query to another.","solutions":["Skip cacheability tuning for ProcedureCall/StoredProcedureQuery instances (instanceof guard).","For HQL queries you are tuning, apply setQueryPlanCacheable on SelectionQuery/MutationQuery only — procedures never plan-cache, so there is nothing to fix for them."],"exampleFix":"// before\nquery.setQueryPlanCacheable(true); // query is a ProcedureCall -> throws\n\n// after\nif (query instanceof org.hibernate.query.SelectionQuery<?> sq) {\n    sq.setQueryPlanCacheable(true);\n}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"static boolean supportsPlanCacheToggle(jakarta.persistence.Query q) {\n    return q instanceof org.hibernate.query.SelectionQuery\n            || q instanceof org.hibernate.query.MutationQuery;\n}","tryCatchPattern":"try {\n    q.setQueryPlanCacheable( true );\n} catch (UnsupportedOperationException e) {\n    // ProcedureCall is never plan-cached; isQueryPlanCacheable() is fixed to false\n}","preventionTips":["Restrict plan-cache tuning to SelectionQuery/MutationQuery.","Remember procedures never enter the query plan cache — exclude them from cache-size analysis."],"tags":["hibernate","stored-procedure","query-plan-cache","performance-tuning"],"backgroundTag":"query-plan-cache-unsupported","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}