hibernate/hibernate-orm · error · HibernateException
Connection lock-timeout does not accept no-wait
Error message
Connection lock-timeout does not accept no-wait
What it means
Hibernate 7 applies pessimistic-lock timeouts on CockroachDB via the JDBC connection setting 'set lock_timeout = N' (CockroachLockingSupport.setLockTimeout -> Helper.setLockTimeout). The value strategy maps WAIT_FOREVER (-1 ms) to 0, so a timeout of 0 ms (Timeouts.NO_WAIT_MILLI, the JPA no-wait magic value) cannot be distinguished from wait-forever and is rejected with this HibernateException. The support level is SUPPORTED, not EXTENDED, so no-wait is never accepted on this path.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/dialect/lock/internal/CockroachLockingSupport.java:110
connection,
factory
);
}
@Override
public void setLockTimeout(
Timeout timeout,
Connection connection,
SessionFactoryImplementor factory) {
Helper.setLockTimeout(
timeout,
(t) -> {
final int milliseconds = timeout.milliseconds();
if ( milliseconds == SKIP_LOCKED_MILLI ) {
throw new HibernateException( "Connection lock-timeout does not accept skip-locked" );
}
if ( milliseconds == NO_WAIT_MILLI ) {
throw new HibernateException( "Connection lock-timeout does not accept no-wait" );
}
return milliseconds == WAIT_FOREVER_MILLI ? 0 : milliseconds;
},
"set lock_timeout = %s",
connection,
factory
);
}
}
View on GitHub (pinned to fad1729dce)
Solutions
- Use the smallest real timeout CockroachDB accepts (e.g. 1-50 ms) to approximate no-wait, or WAIT_FOREVER (-1) to wait indefinitely
- If you need true no-wait, use a locking clause variant supported by the database (native 'FOR UPDATE NOWAIT') instead of the connection-level timeout
- Check dialect.getLockingSupport().getConnectionLockTimeoutStrategy().getSupportedLevel(): only Level.EXTENDED (SQL Server/Sybase) accepts no-wait
- Remove global 'jakarta.persistence.lock.timeout' = 0 settings that apply to every pessimistic lock
Example fix
// before
Map<String, Object> hints = Map.of("jakarta.persistence.lock.timeout", 0); // NO_WAIT -> throws
em.find(Order.class, id, LockModeType.PESSIMISTIC_WRITE, hints);
// after: short real wait approximating no-wait on CockroachDB
Map<String, Object> hints = Map.of("jakarta.persistence.lock.timeout", 50);
em.find(Order.class, id, LockModeType.PESSIMISTIC_WRITE, hints); Defensive patterns
Strategy: validation
Validate before calling
int millis = lockOptions.getTimeOut();
ConnectionLockTimeoutStrategy.Level level = sessionFactory.getJdbcServices().getDialect()
.getLockingSupport().getConnectionLockTimeoutStrategy().getSupportedLevel();
if (millis == Timeouts.NO_WAIT_MILLI && level != ConnectionLockTimeoutStrategy.Level.EXTENDED) {
lockOptions.setTimeOut(50); // 0 (no-wait) only works on EXTENDED dialects (SQL Server/Sybase)
} Type guard
static boolean acceptsConnectionTimeout(ConnectionLockTimeoutStrategy s, int millis) {
if (s.getSupportedLevel() == ConnectionLockTimeoutStrategy.Level.NONE) return false;
if (millis == Timeouts.SKIP_LOCKED_MILLI) return false;
return millis != Timeouts.NO_WAIT_MILLI
|| s.getSupportedLevel() == ConnectionLockTimeoutStrategy.Level.EXTENDED;
} Try / catch
try {
em.find(Order.class, id, LockModeType.PESSIMISTIC_WRITE, hints);
} catch (HibernateException e) {
if (e.getMessage() != null && e.getMessage().contains("does not accept no-wait")) {
hints = Map.of("jakarta.persistence.lock.timeout", 50); // retry with a real timeout
} else { throw e; }
} Prevention
- Do not use the JPA hint value 0 as a portable no-wait; only SQL Server/Sybase (Level.EXTENDED) accept it at connection level
- Approximate no-wait with a small positive timeout plus PessimisticLockException handling
- Audit persistence.xml and repository hints for lock.timeout = 0 or -2
- Test lock scenarios against every production database
When it happens
Trigger: session.buildLockRequest(LockOptions.UPGRADE_NOWAIT).lock(entity) or lockOptions.setTimeOut(0); em.find(id, PESSIMISTIC_WRITE, hints) with 'jakarta.persistence.lock.timeout'=0 (or legacy javax prefix); Timeouts.NO_WAIT reaching setLockTimeout when the dialect routes lock timeouts through the connection (LockTimeoutType.CONNECTION).
Common situations: Copy-pasted 'fail fast' locking code that uses the JPA hint value 0 for no-wait; a global lock.timeout=0 property in persistence.xml; switching an application from SQL Server (where no-wait works, Level.EXTENDED) to CockroachDB; Hibernate 6 to 7 migrations where lock timeout handling moved to ConnectionLockTimeoutStrategy.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Connection lock-timeout does not accept skip-locked
- Connection lock-timeout does not accept no-wait
- Connection lock-timeout does not accept no-wait
- Connection lock-timeout does not accept skip-locked
- Connection lock-timeout does not accept skip-locked
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/72d1b2869d00ef11.
Report an issue: GitHub.