{"record":{"id":"46848561318cc571","repo":"hibernate/hibernate-orm","slug":"spanner-does-not-support-no-wait-468485","errorCode":null,"errorMessage":"Spanner does not support no wait.","messagePattern":"Spanner does not support no wait\\.","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/dialect/SpannerPostgreSQLDialect.java","lineNumber":538,"sourceCode":"\t@Override\n\tpublic LockingClauseStrategy getLockingClauseStrategy(\n\t\t\tQuerySpec querySpec, LockOptions lockOptions) {\n\t\tif ( lockOptions == null ) {\n\t\t\treturn NON_CLAUSE_STRATEGY;\n\t\t}\n\t\tvalidateSpannerLockTimeout( lockOptions.getTimeOut() );\n\t\treturn super.getLockingClauseStrategy( querySpec, lockOptions );\n\t}\n\n\tprivate static void validateSpannerLockTimeout(int millis) {\n\t\tif ( Timeouts.isRealTimeout( millis ) ) {\n\t\t\tthrow new UnsupportedOperationException( \"Spanner does not support lock timeout.\" );\n\t\t}\n\t\tif ( millis == Timeouts.SKIP_LOCKED_MILLI ) {\n\t\t\tthrow new UnsupportedOperationException( \"Spanner does not support skip locked.\" );\n\t\t}\n\t\tif ( millis == Timeouts.NO_WAIT_MILLI ) {\n\t\t\tthrow new UnsupportedOperationException( \"Spanner does not support no wait.\" );\n\t\t}\n\t}\n\n\t@Override\n\tpublic void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {\n\t\tsuper.contributeTypes( typeContributions, serviceRegistry );\n\n\t\tfinal var configurationService = serviceRegistry.requireService( ConfigurationService.class );\n\n\t\tthis.useIntegerForPrimaryKey = configurationService.getSetting(\n\t\t\t\tUSE_INTEGER_FOR_PRIMARY_KEY,\n\t\t\t\tStandardConverters.BOOLEAN,\n\t\t\t\tfalse\n\t\t);\n\n\t\tthis.useEmulator = configurationService.getSetting(\n\t\t\t\tUSE_EMULATOR,\n\t\t\t\tStandardConverters.BOOLEAN,","sourceCodeStart":520,"sourceCodeEnd":556,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/dialect/SpannerPostgreSQLDialect.java#L520-L556","documentation":"This is the NO_WAIT branch of SpannerPostgreSQLDialect.validateSpannerLockTimeout(): millis == Timeouts.NO_WAIT_MILLI throws UnsupportedOperationException('Spanner does not support no wait.'). Called from getLockingClauseStrategy() during query translation, it rejects the no-wait sentinel because the Spanner PostgreSQL interface has no FOR UPDATE NOWAIT. Positive timeouts and skip-locked are refused by the adjacent branches with their own messages.","triggerScenarios":"Pessimistic locking with LockOptions.NO_WAIT / Timeouts.NO_WAIT_MILLI (commonly jakarta.persistence.lock.timeout with the no-wait encoding, or lo.setTimeOut(LockOptions.NO_WAIT)) on a SpannerPostgreSQLDialect connection; validation happens in getLockingClauseStrategy before SQL is emitted.","commonSituations":"Deadlock-shy codebases that set NO_WAIT globally on PostgreSQL being deployed to Spanner PG; oracle-style fail-fast locking; generic service-layer lock aspects reused across datasources.","solutions":["Omit the NO_WAIT timeout on Spanner PG — plain PESSIMISTIC_WRITE/FOR UPDATE is supported.","Achieve fail-fast with a short transaction timeout rather than a lock modifier.","Catch UnsupportedOperationException at the locking boundary and retry without the option.","Centralize lock configuration per datasource profile and strip lock.timeout for Spanner."],"exampleFix":"// before\nLockOptions lo = new LockOptions(LockMode.PESSIMISTIC_WRITE);\nlo.setTimeOut(LockOptions.NO_WAIT);\nq.setLockOptions(lo);\n\n// after\nq.setLockMode(LockMode.PESSIMISTIC_WRITE); // no timeout modifiers","handlingStrategy":"validation","validationCode":"if (lockOptions.getTimeOut() == Timeouts.NO_WAIT_MILLI && dialect instanceof SpannerPostgreSQLDialect) {\n  lockOptions.setTimeOut(LockOptions.NO_TIMEOUT);\n}","typeGuard":null,"tryCatchPattern":"try { return query.getResultList(); }\ncatch (UnsupportedOperationException e) {\n  if (e.getMessage().contains(\"no wait\")) { /* retry with default lock options */ }\n  throw e;\n}","preventionTips":["Remove NO_WAIT settings from Spanner PG lock code.","Use transaction timeouts for fail-fast semantics.","Centralize per-dialect lock profiles."],"tags":["hibernate","cloud-spanner","spanner-postgresql","locking","nowait","unsupportedoperationexception"],"backgroundTag":"nowait-not-supported","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}