hibernate/hibernate-orm · error · UnsupportedOperationException

Entity graph not supported for ProcedureCall

Error message

Entity graph not supported for ProcedureCall

What it means

setEntityGraph(graph, semantic) attaches a fetch graph so a JPQL/HQL selection eagerly fetches chosen associations. Hibernate never translates a stored-procedure call, so its fetching cannot be altered by a graph; ProcedureCallImpl therefore throws UnsupportedOperationException. The method is deprecated on this path — graphs are a SelectionQuery feature only.

Source

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

	@Override
	@Nonnull
	public ProcedureCallImplementor<R> setLockMode(@Nonnull LockModeType lockMode) {
		throw new IllegalStateException( "Locking not supported for ProcedureCall" );
	}

	@Override
	@Nonnull
	public ProcedureCallImplementor<R> addQueryHint(@Nonnull String hint) {
		checkNotClosed();
		super.addQueryHint( hint );
		return this;
	}

	@Override @Deprecated
	@SuppressWarnings("removal")
	@Nonnull
	public Query<R> setEntityGraph(@Nonnull EntityGraph<? super R> graph, @Nonnull GraphSemantic semantic) {
		throw new UnsupportedOperationException( "Entity graph not supported for ProcedureCall" );
	}

	@Override @Deprecated
	@SuppressWarnings("removal")
	@Nonnull
	public Query<R> enableFetchProfile(@Nonnull String profileName) {
		throw new UnsupportedOperationException( "Fetch profiles not supported for ProcedureCall" );
	}

	@Override @Deprecated
	@SuppressWarnings("removal")
	@Nonnull
	public Query<R> disableFetchProfile(@Nonnull String profileName) {
		throw new UnsupportedOperationException( "Fetch profiles not supported for ProcedureCall" );
	}

	@Override
	public boolean isQueryPlanCacheable() {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Apply graphs only after an instanceof SelectionQuery check.
  2. If procedure results under-fetch, return the associated columns from the procedure and map them explicitly via SqlResultSetMapping/constructor expressions.

Example fix

// before
query.setEntityGraph(graph, GraphSemantic.FETCH); // query is a ProcedureCall -> throws

// after
if (query instanceof org.hibernate.query.SelectionQuery<?> sq) {
    sq.setEntityGraph(graph, GraphSemantic.FETCH);
}
// procedure path: rely on the procedure's own result mapping
Defensive patterns

Strategy: type-guard

Type guard

static boolean supportsEntityGraph(jakarta.persistence.Query q) {
    return q instanceof org.hibernate.query.SelectionQuery;
}

Try / catch

try {
    q.setEntityGraph( graph, semantic );
} catch (UnsupportedOperationException e) {
    // procedure call: fetching cannot be altered; rely on the procedure's result mapping
}

Prevention

When it happens

Trigger: Calling setEntityGraph(graph, GraphSemantic.FETCH) on a ProcedureCall, typically from generic repository code that applies graphs to every Query to fix lazy-loading issues.

Common situations: N+1 remediation passes that attach graphs globally; shared query executors taking (Query, EntityGraph); upgrading code where setEntityGraph compiled fine on HQL queries but also receives procedure calls.

Related errors


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