hibernate/hibernate-orm · error · SemanticException
The 'from' clause of a subquery has a 'fetch' join
Error message
The 'from' clause of a subquery has a 'fetch' join
What it means
In getJoin, the join target is a subquery (JoinSubqueryContext - e.g. 'join lateral (select ...) s') and the join was marked 'fetch'. A derived join over a subquery result is not a managed association, so there is nothing to fetch; Hibernate throws SemanticException.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java:2355
}
else {
throw new ParsingException( "unexpected join type" );
}
}
@SuppressWarnings("unchecked")
private <X> SqmJoin<X, ?> getJoin(
SqmRoot<X> sqmRoot,
SqmJoinType joinType,
HqlParser.JoinTargetContext joinTargetContext,
String alias,
boolean fetch) {
if ( joinTargetContext instanceof HqlParser.JoinPathContext joinPathContext ) {
return (SqmJoin<X, ?>) joinPathContext.path().accept( this );
}
else if ( joinTargetContext instanceof HqlParser.JoinSubqueryContext joinSubqueryContext ) {
if ( fetch ) {
throw new SemanticException( "The 'from' clause of a subquery has a 'fetch' join", query );
}
if ( getCreationOptions().useStrictJpaCompliance() ) {
throw new StrictJpaComplianceViolation(
"The JPA specification does not support subqueries in the from clause. " +
"Please disable the JPA query compliance if you want to use this feature.",
StrictJpaComplianceViolation.Type.FROM_SUBQUERY
);
}
final boolean lateral = joinSubqueryContext.LATERAL() != null;
final var identifierConsumer = dotIdentifierConsumerStack.pop();
final var subQuery = (SqmSubQuery<X>) joinSubqueryContext.subquery().accept( this );
dotIdentifierConsumerStack.push( identifierConsumer );
final var join = new SqmDerivedJoin<>( subQuery, alias, joinType, lateral, sqmRoot );
processingStateStack.getCurrent().getPathRegistry().register( join );
return join;
}
else if ( joinTargetContext instanceof HqlParser.JoinFunctionContext joinFunctionContext ) {View on GitHub (pinned to fad1729dce)
Solutions
- Remove the 'fetch' keyword from the subquery join: 'join lateral (select ...) s'
- Fetch only real, mapped associations of your roots
Example fix
// before select e from Employee e join fetch lateral (select i from Item i where i.emp = e) s // after select e from Employee e join lateral (select i from Item i where i.emp = e) s
Defensive patterns
Strategy: validation
Validate before calling
// Reject 'join fetch lateral (select ...)' style constructs before execution
static boolean fetchOnSubqueryJoin(String hql) {
return java.util.regex.Pattern.compile("join\\s+fetch\\s+(lateral\\s*)?\\(", java.util.regex.Pattern.CASE_INSENSITIVE).matcher(hql).find();
}
if (fetchOnSubqueryJoin(hql)) throw new IllegalArgumentException("'fetch' is not valid on joins targeting a subquery"); Try / catch
try {
return em.createQuery(hql, Employee.class).getResultList();
} catch (org.hibernate.query.sqm.SemanticException e) {
if (e.getMessage() != null && e.getMessage().contains("'fetch' join")) {
throw new IllegalArgumentException("Remove 'fetch' from the (lateral) subquery join", e);
}
throw e;
} Prevention
- Apply 'fetch' only to mapped associations, never to derived/lateral subquery joins
- When introducing lateral joins (Hibernate 6.6+), review every join for stale fetch keywords
When it happens
Trigger: 'select e from Employee e join fetch lateral (select ...) s on ...'; any 'join fetch' whose target is a (lateral) subquery in the from clause.
Common situations: Copy-pasting 'fetch' onto lateral joins adopted with Hibernate 6.6+; assuming fetch works uniformly on every join kind.
Related errors
- The 'from' clause of a subquery has a 'fetch'
- Implicitly-polymorphic domain path in subquery '${name}'
- Could not resolve entity or correlation path '${name}'
- FROM_SUBQUERY
- ALIASED_FETCH_JOIN
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/e15c359a5949972b.
Report an issue: GitHub.