{"record":{"id":"86ae6a728809dd1c","repo":"hibernate/hibernate-orm","slug":"lock-mode-not-valid-for-locking-via-update-st","errorCode":null,"errorMessage":"Lock mode {} not valid for locking via 'update' statement","messagePattern":"Lock mode (.+?) not valid for locking via 'update' statement","errorType":"exception","errorClass":"HibernateException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/dialect/lock/UpdateLockingStrategy.java","lineNumber":38,"sourceCode":" * @author Steve Ebersole\n * @since 3.2\n *\n * @deprecated No longer used\n */\n@Deprecated(since = \"7.2\", forRemoval = true)\npublic class UpdateLockingStrategy extends AbstractPessimisticUpdateLockingStrategy {\n\n\t/**\n\t * Construct a locking strategy based on SQL UPDATE statements.\n\t *\n\t * @param lockable The metadata for the entity to be locked.\n\t * @param lockMode Indicates the type of lock to be acquired.  Note that\n\t * read-locks are not valid for this strategy.\n\t */\n\tpublic UpdateLockingStrategy(EntityPersister lockable, LockMode lockMode) {\n\t\tsuper( lockable, lockMode );\n\t\tif ( lockMode.lessThan( LockMode.WRITE ) ) {\n\t\t\tthrow new HibernateException( \"Lock mode \" + lockMode + \" not valid for locking via 'update' statement\" );\n\t\t}\n\t}\n\n\t@Override\n\tpublic void lock(Object id, Object version, Object object, int timeout, SharedSessionContractImplementor session)\n\t\t\tthrows StaleObjectStateException, JDBCException {\n\t\tdoLock( id, version, session );\n\t}\n}\n","sourceCodeStart":20,"sourceCodeEnd":48,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/dialect/lock/UpdateLockingStrategy.java#L20-L48","documentation":"UpdateLockingStrategy is the concrete dialect-facing strategy that emulates locking with an SQL UPDATE; besides the base-class check (>= PESSIMISTIC_READ) it enforces an even higher bar: LockMode must be at least LockMode.WRITE, otherwise HibernateException 'Lock mode <mode> not valid for locking via 'update' statement'. The class comment notes read-locks are not valid for this strategy. The check runs in the constructor, so it fails as soon as the dialect builds the strategy.","triggerScenarios":"A dialect that cannot 'select ... for update' maps locking to UpdateLockingStrategy, and a lock request arrives with a mode below WRITE - e.g. session.lock(entity, LockMode.PESSIMISTIC_READ) or a legacy LockMode.UPGRADE/READ - making lockMode.lessThan(LockMode.WRITE) true. Direct new UpdateLockingStrategy(persister, LockMode.PESSIMISTIC_READ) reproduces it too.","commonSituations":"Databases/dialects where row locks are only emulated via UPDATE; legacy code using LockMode.UPGRADE; custom dialects returning UpdateLockingStrategy for modes it cannot honor; tests constructing strategies directly.","solutions":["Request PESSIMISTIC_WRITE or stronger when the dialect locks via UPDATE","In custom dialects, return this strategy only for WRITE-and-above modes and use a select-based strategy for PESSIMISTIC_READ","Replace legacy LockMode.UPGRADE/READ constants with PESSIMISTIC_WRITE where update locking is in play"],"exampleFix":"// before\nsession.buildLockRequest(new LockOptions(LockMode.PESSIMISTIC_READ)).lock(item);\n\n// after\nsession.buildLockRequest(new LockOptions(LockMode.PESSIMISTIC_WRITE)).lock(item);","handlingStrategy":"validation","validationCode":"// Clamp the mode to WRITE+ before requesting update-based locks\nstatic LockMode atLeastWrite(LockMode m) {\n    return m.lessThan(LockMode.WRITE) ? LockMode.PESSIMISTIC_WRITE : m;\n}\nsession.buildLockRequest(new LockOptions(atLeastWrite(mode))).lock(item);","typeGuard":null,"tryCatchPattern":"try {\n    session.buildLockRequest(new LockOptions(mode)).lock(item);\n}\ncatch (HibernateException e) {\n    if (e.getMessage().contains(\"not valid for locking via 'update' statement\")) {\n        throw new IllegalArgumentException(\"UpdateLockingStrategy requires LockMode.WRITE or stronger (got \" + mode + \")\", e);\n    }\n    throw e;\n}","preventionTips":["On dialects that emulate locks with UPDATE, always request PESSIMISTIC_WRITE or stronger","Know your dialect's getLockingStrategy mapping before mixing weak and strong lock modes","Centralize lock-mode selection in one helper so thresholds are enforced in a single place"],"tags":["hibernate","locking","pessimistic-lock","lock-mode","update-locking"],"backgroundTag":"invalid-lock-mode","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}