hibernate/hibernate-orm · error · IllegalArgumentException

Cannot correlate from node [${parentFrom}]

Error message

Cannot correlate from node [${parentFrom}]

What it means

The one-arg correlate(From) is a dispatcher: it only knows how to correlate parent From nodes that are a Root, a Join, a JpaCrossJoin, or a JpaEntityJoin. Any other From implementation — e.g. a CTE root (SqmCteRoot), a derived/dynamic-instantiation root, or some other synthetic node — cannot be brought into the subquery and throws IllegalArgumentException naming the node.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/select/SqmSubQuery.java:540

	@Nonnull
	@Override
	public <X, Y> SqmFrom<X, Y> correlate(@Nonnull From<X, Y> parentFrom) {
		if ( parentFrom instanceof Root<?> ) {
			//noinspection unchecked
			return (SqmFrom<X, Y>) correlate( (Root<Y>) parentFrom );
		}
		else if ( parentFrom instanceof Join<?, ?> ) {
			return correlate( (Join<X, Y>) parentFrom );
		}
		else if ( parentFrom instanceof JpaCrossJoin<?, ?> ) {
			return (SqmFrom<X, Y>) correlate( (JpaCrossJoin<X, Y>) parentFrom );
		}
		else if ( parentFrom instanceof JpaEntityJoin<?, ?> ) {
			return (SqmFrom<X, Y>) correlate( (JpaEntityJoin<T, Y>) parentFrom );
		}
		else {
			throw new IllegalArgumentException( "Cannot correlate from node [" + parentFrom + "]" );
		}
	}

	@Nonnull
	@Override
	public <X, Y> SqmCorrelatedJoin<X, Y> correlate(@Nonnull Join<X, Y> join) {
		if ( join instanceof PluralJoin<?, ?, ?> pluralJoin ) {
			return switch ( pluralJoin.getModel().getCollectionType() ) {
				case COLLECTION -> correlate( (CollectionJoin<X, Y>) join );
				case LIST -> correlate( (ListJoin<X, Y>) join );
				case SET -> correlate( (SetJoin<X, Y>) join );
				case MAP -> correlate( (MapJoin<X, ?, Y>) join );
			};
		}
		final SqmCorrelatedSingularValuedJoin<X, Y> correlated =
				( (SqmSingularValuedJoin<X, Y>) join ).createCorrelation();
		getQuerySpec().addRoot( correlated.getCorrelatedRoot() );
		return correlated;

View on GitHub (pinned to fad1729dce)

Solutions

  1. Correlate the underlying entity Root or a concrete Join instead of the CTE/derived root
  2. Inside the subquery, reference the CTE by joining to it (cb cross/entity join or JpaCteCriteria attribute join) rather than correlating it
  3. If you handle From nodes generically, branch on Root/Join/JpaCrossJoin/JpaEntityJoin and fail with your own clear message for other kinds

Example fix

// before
JpaCteCriteria<Long> cte = query.with("totals", ...);
Root<?> cteRoot = (Root<?>) cte; // synthetic root
sub.correlate(cteRoot); // IllegalArgumentException: Cannot correlate from node

// after
Root<Order> orderRoot = query.from(Order.class);
sub.correlate(orderRoot); // correlate a real entity root
sub.select(...).where(cb.equal(subRoot.get("id"), orderRoot.get("id")));
Defensive patterns

Strategy: type-guard

Validate before calling

if (from instanceof Root || from instanceof Join || from instanceof JpaCrossJoin || from instanceof JpaEntityJoin) { sub.correlate(from); } else { throw new IllegalArgumentException("Unsupported From node for correlation: " + from); }

Type guard

static boolean isCorrelatable(From<?, ?> from) {
    return from instanceof Root || from instanceof Join
            || from instanceof JpaCrossJoin || from instanceof JpaEntityJoin;
}

Try / catch

try { sub.correlate(from); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("Cannot correlate")) { /* correlate the underlying entity root instead */ } else throw e; }

Prevention

When it happens

Trigger: subquery.correlate(fromNode) where fromNode is a root obtained from a CTE (query.with(...) then cteRoot), a SqmDerivedRoot from a dynamic instantiation, or any non-standard From you received from generic traversal code rather than from query.from(Entity.class) / joins.

Common situations: CTE-based criteria queries where the developer correlates the CTE root into a subquery instead of an entity root; generic frameworks that accept an arbitrary From and call correlate() on it; refactors that changed which root a subquery correlates.

Related errors


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