{"record":{"id":"9790bb6acb92ea4f","repo":"hibernate/hibernate-orm","slug":"locking-not-supported-for-procedurecall","errorCode":null,"errorMessage":"Locking not supported for ProcedureCall","messagePattern":"Locking not supported for ProcedureCall","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/procedure/internal/ProcedureCallImpl.java","lineNumber":322,"sourceCode":"\t@Nonnull\n\tpublic ProcedureCallImplementor<R> setMaxResults(int maxResult) {\n\t\tcheckNotClosed();\n\t\tsuper.setMaxResults( maxResult );\n\t\treturn this;\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic ProcedureCallImplementor<R> setFirstResult(int startPosition) {\n\t\tcheckNotClosed();\n\t\tsuper.setFirstResult( startPosition );\n\t\treturn this;\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic ProcedureCallImplementor<R> setLockMode(@Nonnull LockModeType lockMode) {\n\t\tthrow new IllegalStateException( \"Locking not supported for ProcedureCall\" );\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic ProcedureCallImplementor<R> addQueryHint(@Nonnull String hint) {\n\t\tcheckNotClosed();\n\t\tsuper.addQueryHint( hint );\n\t\treturn this;\n\t}\n\n\t@Override @Deprecated\n\t@SuppressWarnings(\"removal\")\n\t@Nonnull\n\tpublic Query<R> setEntityGraph(@Nonnull EntityGraph<? super R> graph, @Nonnull GraphSemantic semantic) {\n\t\tthrow new UnsupportedOperationException( \"Entity graph not supported for ProcedureCall\" );\n\t}\n\n\t@Override @Deprecated","sourceCodeStart":304,"sourceCodeEnd":340,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/procedure/internal/ProcedureCallImpl.java#L304-L340","documentation":"StoredProcedureQuery inherits setLockMode(LockModeType) from the JPA Query contract, and the JPA specification requires IllegalStateException when locking is requested on a stored-procedure query. ProcedureCallImpl implements exactly that (see the source comment on getLockMode): pessimistic locking is a Hibernate/JPA translation feature with no meaning for a database call.","triggerScenarios":"Calling setLockMode(LockModeType.PESSIMISTIC_WRITE) (or OPTIMISTIC) on a StoredProcedureQuery/ProcedureCall — usually from generic DAO code that applies a lock mode to every query in a write transaction.","commonSituations":"Reusable repository layers with a findByQuery(Query q, LockModeType lock) method; @Lock annotations on repository methods that end up invoking procedures; copy-pasted query-building helpers.","solutions":["Guard with instanceof: skip setLockMode when the query is a ProcedureCall/StoredProcedureQuery.","If row locking is genuinely needed, do SELECT ... FOR UPDATE inside the procedure/function itself.","Split the generic API so locking applies only to selection queries."],"exampleFix":"// before\njakarta.persistence.Query q = em.createStoredProcedureQuery(\"reserve_stock\");\nq.setLockMode(LockModeType.PESSIMISTIC_WRITE); // throws IllegalStateException\n\n// after\nif (q instanceof StoredProcedureQuery) {\n    // locking handled inside the procedure (SELECT ... FOR UPDATE)\n} else {\n    q.setLockMode(LockModeType.PESSIMISTIC_WRITE);\n}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"static boolean supportsLocking(jakarta.persistence.Query q) {\n    return !( q instanceof org.hibernate.procedure.ProcedureCall )\n            && !( q instanceof StoredProcedureQuery );\n}","tryCatchPattern":"try {\n    q.setLockMode( lockMode );\n} catch (IllegalStateException e) {\n    // spec-required failure for procedure calls; locking belongs inside the procedure\n}","preventionTips":["Guard setLockMode with instanceof StoredProcedureQuery in generic DAOs.","Implement locking inside the procedure (SELECT ... FOR UPDATE) where needed.","Do not annotate repository methods that call procedures with @Lock."],"tags":["hibernate","stored-procedure","locking","jpa"],"backgroundTag":"locking-not-supported","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}