hibernate/hibernate-orm · error · HibernateException

Connection lock-timeout does not accept skip-locked

Error message

Connection lock-timeout does not accept skip-locked

What it means

GaussDBLockingSupport implements the connection-level lock timeout by executing 'set local lockwait_timeout = <ms>' before the locking statement. Hibernate's Timeout API encodes skip-locked as the sentinel value SKIP_LOCKED_MILLI (not a duration); since lockwait_timeout is a plain millisecond setting that cannot express 'skip locked', setLockTimeout throws this HibernateException ('Connection lock-timeout does not accept skip-locked').

Source

Thrown at hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/lock/internal/GaussDBLockingSupport.java:130

	private static int getTimeout(String value, int unitLength) {
		final int number;
		try {
			number = Integer.parseInt( value.substring( 0, value.length() - unitLength ) );
		}
		catch (NumberFormatException e) {
			throw new RuntimeException( e );
		}
		return number;
	}

	@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 local lockwait_timeout = %s",
				connection,
				factory
		);
	}
}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Do not request skip-locked via the lock timeout on GaussDB: use Timeout.milliseconds(n) or Timeout.waitForever() instead.
  2. Get SKIP LOCKED semantics through row-level locking in the query itself (setLockMode / LockOptions with skip-locked follow-on locking) rather than the connection lock-timeout.
  3. Remove the 'jakarta.persistence.lock.timeout' = -2 hint from the query/entity-manager properties on this database.
  4. Catch the HibernateException and degrade to a bounded wait timeout.

Example fix

// before - throws on GaussDB
query.setLockTimeout(Timeout.skipLocked());

// after - bounded wait, or rely on query lock options
query.setLockTimeout(Timeout.milliseconds(5000));
Defensive patterns

Strategy: validation

Validate before calling

boolean gauss = sessionFactory.getJdbcServices().getDialect() instanceof org.hibernate.community.dialect.GaussDBDialect;
Timeout t = gauss && requested.isSkipLocked()
        ? Timeout.milliseconds(5000)  // substitute a bounded wait
        : requested;

Type guard

static boolean usableAsConnectionLockTimeout(Timeout t) {
    // reject the sentinels that are not durations
    return !t.isSkipLocked() && !t.isNoWait();
}

Try / catch

try {
    query.setLockTimeout(Timeout.skipLocked()).getResultList();
} catch (HibernateException e) {
    if (e.getMessage().contains("skip-locked")) {
        query.setLockTimeout(Timeout.milliseconds(5000)).getResultList(); // graceful degrade
    } else throw e;
}

Prevention

When it happens

Trigger: On GaussDB/openGauss, setting a lock timeout of Timeout.skipLocked() - e.g. selectionQuery.setLockTimeout(Timeout.skipLocked()) or the equivalent 'jakarta.persistence.lock.timeout' = -2 (LockOptions.SKIP_LOCKED) when the dialect applies it at the connection level. The LockTimeoutHandler calls GaussDBLockingSupport.setLockTimeout, which rejects the sentinel milliseconds value.

Common situations: Queue/batch-processing code using SKIP LOCKED semantics ported to GaussDB; setting the JPA lock.timeout hint to -2 globally; switching dialects from PostgreSQL (which translates skip-locked into lock_timeout handling differently) to GaussDB.

Understand the failure class

Related errors


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/df3076f1adf061e7. Report an issue: GitHub.