hibernate/hibernate-orm · error · UnsupportedOperationException
Spanner does not support no wait.
Error message
Spanner does not support no wait.
What it means
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.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/dialect/SpannerPostgreSQLDialect.java:538
@Override
public LockingClauseStrategy getLockingClauseStrategy(
QuerySpec querySpec, LockOptions lockOptions) {
if ( lockOptions == null ) {
return NON_CLAUSE_STRATEGY;
}
validateSpannerLockTimeout( lockOptions.getTimeOut() );
return super.getLockingClauseStrategy( querySpec, lockOptions );
}
private static void validateSpannerLockTimeout(int millis) {
if ( Timeouts.isRealTimeout( millis ) ) {
throw new UnsupportedOperationException( "Spanner does not support lock timeout." );
}
if ( millis == Timeouts.SKIP_LOCKED_MILLI ) {
throw new UnsupportedOperationException( "Spanner does not support skip locked." );
}
if ( millis == Timeouts.NO_WAIT_MILLI ) {
throw new UnsupportedOperationException( "Spanner does not support no wait." );
}
}
@Override
public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
super.contributeTypes( typeContributions, serviceRegistry );
final var configurationService = serviceRegistry.requireService( ConfigurationService.class );
this.useIntegerForPrimaryKey = configurationService.getSetting(
USE_INTEGER_FOR_PRIMARY_KEY,
StandardConverters.BOOLEAN,
false
);
this.useEmulator = configurationService.getSetting(
USE_EMULATOR,
StandardConverters.BOOLEAN,View on GitHub (pinned to fad1729dce)
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.
Example fix
// before LockOptions lo = new LockOptions(LockMode.PESSIMISTIC_WRITE); lo.setTimeOut(LockOptions.NO_WAIT); q.setLockOptions(lo); // after q.setLockMode(LockMode.PESSIMISTIC_WRITE); // no timeout modifiers
Defensive patterns
Strategy: validation
Validate before calling
if (lockOptions.getTimeOut() == Timeouts.NO_WAIT_MILLI && dialect instanceof SpannerPostgreSQLDialect) {
lockOptions.setTimeOut(LockOptions.NO_TIMEOUT);
} Try / catch
try { return query.getResultList(); }
catch (UnsupportedOperationException e) {
if (e.getMessage().contains("no wait")) { /* retry with default lock options */ }
throw e;
} Prevention
- Remove NO_WAIT settings from Spanner PG lock code.
- Use transaction timeouts for fail-fast semantics.
- Centralize per-dialect lock profiles.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Spanner doesn't support for-update with no-wait timeout
- Spanner doesn't support for-update with skip locked timeout
- Spanner does not support lock timeout.
- Spanner does not support skip locked.
- Spanner does not support no wait.
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/46848561318cc571.
Report an issue: GitHub.