hibernate/hibernate-orm · error · IllegalStateException

Illegal attempt to get lock mode for a procedure call

Error message

Illegal attempt to get lock mode for a procedure call

What it means

The JPA specification requires Query.getLockMode() to throw IllegalStateException when the query is not a JPQL/Criteria selection query; ProcedureCallImpl follows the spec (the source comment notes the logically-fitting exception would be UnsupportedOperationException, but the spec wins). Any attempt to read the lock mode of a procedure call therefore fails.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/procedure/internal/ProcedureCallImpl.java:398

		super.setTimeout( timeout );
		return this;
	}

	@Override
	@Nonnull
	public ProcedureCallImplementor<R> setTimeout(@Nullable Timeout timeout) {
		checkNotClosed();
		super.setTimeout( timeout );
		return this;
	}

	@Override
	@Deprecated @SuppressWarnings("removal")
	@Nullable
	public LockModeType getLockMode() {
		// the JPA spec requires IllegalStateException here, even
		// though it's logically an UnsupportedOperationException
		throw new IllegalStateException( "Illegal attempt to get lock mode for a procedure call" );
	}

	@Override
	@Nonnull
	public ProcedureCallImplementor<R> setFlushMode(@Nonnull FlushModeType flushModeType) {
		checkNotClosed();
		super.setFlushMode( flushModeType );
		return this;
	}

	public List<ResultSetMapping> getResultSetMappings() {
		return resultSetMappings;
	}

	@Override
	@Nonnull
	public ProcedureCallImplementor<R> setCacheRetrieveMode(@Nonnull CacheRetrieveMode cacheRetrieveMode) {
		checkNotClosed();

View on GitHub (pinned to fad1729dce)

Solutions

  1. Guard with instanceof StoredProcedureQuery/ProcedureCall before calling getLockMode().
  2. For audit data, read getHints() instead, which works on all query types.
  3. Push lock-mode introspection behind a helper that only accepts SelectionQuery.

Example fix

// before
LockModeType mode = query.getLockMode(); // query is a StoredProcedureQuery -> throws

// after
LockModeType mode = (query instanceof StoredProcedureQuery)
        ? null  // locking is not applicable to procedure calls
        : query.getLockMode();
Defensive patterns

Strategy: type-guard

Type guard

static boolean supportsLockMode(jakarta.persistence.Query q) {
    return !( q instanceof StoredProcedureQuery );
}

Try / catch

try {
    LockModeType mode = q.getLockMode();
} catch (IllegalStateException e) {
    // spec-required: procedure calls have no lock mode
}

Prevention

When it happens

Trigger: Calling getLockMode() on a StoredProcedureQuery/ProcedureCall — usually generic code that snapshots a query's lock state for logging, auditing, or metrics.

Common situations: Observability wrappers that record lock modes of all executed queries; assertion helpers in tests that inspect query configuration; tracing interceptors around em.createQuery calls.

Related errors


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