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
- Correlate the underlying entity Root or a concrete Join instead of the CTE/derived root
- Inside the subquery, reference the CTE by joining to it (cb cross/entity join or JpaCteCriteria attribute join) rather than correlating it
- 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
- Only correlate roots and joins obtained from query.from(Entity.class) or explicit joins
- For CTE roots, join to the CTE inside the subquery rather than correlating it
- Type generic correlation helpers against Root/Join, not the raw From interface
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
- Not correlated
- Correlated derived root does not have an entity type. Use ge
- Correlated derived root does not have an entity type. Use ge
- Can't set alias on a correlated root
- Could not resolve entity or correlation path '${name}'
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/fb63dc697acfe0d6.
Report an issue: GitHub.