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
On MySQL, Hibernate sets pessimistic-lock timeouts through 'SET @@SESSION.innodb_lock_wait_timeout = N'. The variable is in whole seconds with allowed range [1, 1073741824], so the no-wait magic value 0 ms (Timeouts.NO_WAIT_MILLI) has no representable value and MySQLLockingSupport throws this HibernateException instead of rounding to 1 second (which would silently wait instead of failing fast). MySQL reports Level.SUPPORTED, not EXTENDED, so no-wait is never accepted here.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/dialect/lock/internal/MySQLLockingSupport.java:139
},
connection,
factory
);
}
@Override
public void setLockTimeout(Timeout timeout, Connection connection, SessionFactoryImplementor factory) {
Helper.setLockTimeout(
timeout,
(t) -> {
// see https://dev.mysql.com/doc/refman/8.4/en/innodb-parameters.html#sysvar_innodb_lock_wait_timeout
// unit: seconds, allowed values: [1, 1073741824]
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" );
}
if ( milliseconds == WAIT_FOREVER_MILLI ) {
return foreverValue;
}
return (int) Math.ceil( (double) milliseconds / 1000);
},
"SET @@SESSION.innodb_lock_wait_timeout = %s",
connection,
factory
);
}
}
}
View on GitHub (pinned to fad1729dce)
Solutions
- Use the smallest real timeout (>= 1 second via innodb_lock_wait_timeout) and handle LockTimeoutException to fail fast, or WAIT_FOREVER (-1) to wait
- If true no-wait is required, use a native 'SELECT ... FOR UPDATE NOWAIT' (MySQL 8+) outside the connection-timeout path
- Guard with getConnectionLockTimeoutStrategy().getSupportedLevel(): no-wait requires Level.EXTENDED (SQL Server/Sybase only)
- Audit and remove lock timeout hints set to 0 in configuration or query hints
Example fix
// before
Map<String, Object> hints = Map.of("jakarta.persistence.lock.timeout", 0); // NO_WAIT -> throws
Order o = em.find(Order.class, id, LockModeType.PESSIMISTIC_WRITE, hints);
// after: 1s wait, catch the timeout to emulate no-wait behavior
Map<String, Object> hints = Map.of("jakarta.persistence.lock.timeout", 1000);
try {
Order o = em.find(Order.class, id, LockModeType.PESSIMISTIC_WRITE, hints);
} catch (PessimisticLockException e) { /* row busy: fail fast */ } Defensive patterns
Strategy: validation
Validate before calling
int millis = lockOptions.getTimeOut();
if (millis <= 0) { // 0 = no-wait, -1 = forever, -2 = skip-locked
// only WAIT_FOREVER (-1) or >=1000ms make sense for MySQL connection timeouts
lockOptions.setTimeOut(millis == Timeouts.WAIT_FOREVER_MILLI ? -1 : 1000);
} 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 {
Order o = 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", 1000);
em.find(Order.class, id, LockModeType.PESSIMISTIC_WRITE, hints);
} else { throw e; }
} Prevention
- Do not assume lock.timeout=0 (no-wait) is portable: MySQL rejects it at connection level
- Prefer a 1s timeout plus PessimisticLockException handling to emulate fail-fast on MySQL
- Use native NOWAIT clauses when true no-wait is required
- Review JPA hints copied from documentation before applying them globally
When it happens
Trigger: session.buildLockRequest(LockOptions.UPGRADE_NOWAIT).lock(entity) or lockOptions.setTimeOut(0); em.find(id, PESSIMISTIC_WRITE) / query locking with hint 'jakarta.persistence.lock.timeout' = 0; Timeouts.NO_WAIT reaching setLockTimeout on MySQL, MariaDB or TiDB dialects that route timeouts through the connection.
Common situations: 'Fail fast' locking recipes copied from JPA documentation that set lock.timeout=0; global persistence.xml property 'jakarta.persistence.lock.timeout'=0 applied to all locks; moving an app from SQL Server/Oracle (where no-wait works) to MySQL; library code shared across databases assuming no-wait is universal.
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 no-wait
- Connection lock-timeout does not accept skip-locked
- 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/d4a1b261846e814f.
Report an issue: GitHub.