hibernate/hibernate-orm · error · IllegalArgumentException
Fetch clause may not be null
Error message
Fetch clause may not be null
What it means
QueryPart.setFetchClauseExpression(Expression, FetchClauseType) backs HQL/JPQL 'fetch first/next' clauses. Passing a non-null expression together with a null FetchClauseType is contradictory - the AST cannot represent 'fetch N' without knowing whether it is ROWS_ONLY, ROWS_WITH_TIES, PERCENT_ONLY or PERCENT_WITH_TIES - so an IllegalArgumentException is thrown. Passing a null expression is the supported way to clear the clause and resets both fields.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/sql/ast/tree/select/QueryPart.java:113
return offsetClauseExpression;
}
public void setOffsetClauseExpression(Expression offsetClauseExpression) {
this.offsetClauseExpression = offsetClauseExpression;
}
public Expression getFetchClauseExpression() {
return fetchClauseExpression;
}
public void setFetchClauseExpression(Expression fetchClauseExpression, FetchClauseType fetchClauseType) {
if ( fetchClauseExpression == null ) {
this.fetchClauseExpression = null;
this.fetchClauseType = FetchClauseType.ROWS_ONLY;
}
else {
if ( fetchClauseType == null ) {
throw new IllegalArgumentException( "Fetch clause may not be null" );
}
this.fetchClauseExpression = fetchClauseExpression;
this.fetchClauseType = fetchClauseType;
}
}
public FetchClauseType getFetchClauseType() {
return fetchClauseType;
}
}
View on GitHub (pinned to fad1729dce)
Solutions
- Pass a concrete FetchClauseType (usually FetchClauseType.ROWS_ONLY) whenever the expression is non-null
- To clear the fetch clause call setFetchClauseExpression(null, null) - the null branch resets both fields
- Validate arguments up front: only (null, ...) or (expr, non-null type) are legal combinations
Example fix
// before queryPart.setFetchClauseExpression( rowCount, null ); // throws // after queryPart.setFetchClauseExpression( rowCount, FetchClauseType.ROWS_ONLY );
Defensive patterns
Strategy: validation
Validate before calling
void applyFetchClause(QueryPart part, Expression expr, FetchClauseType type) {
if ( expr == null ) {
part.setFetchClauseExpression( null, null );
} else {
Objects.requireNonNull( type, "FetchClauseType required for non-null expression" );
part.setFetchClauseExpression( expr, type );
}
} Prevention
- Always pair a non-null fetch expression with a concrete FetchClauseType (usually ROWS_ONLY)
- Clear fetch clauses with setFetchClauseExpression(null, null)
- Treat (expr != null && type == null) as a programmer error and assert it before calling
When it happens
Trigger: Programmatic construction of a QueryPart (custom translators, criteria-to-SQL AST code) calling setFetchClauseExpression(expr, null); copy/clone routines that copy the expression but not the type; misuse of the setter with a non-null expression and missing type.
Common situations: Custom SqmTranslator/SqlAstCreation extensions building pagination; porting code between Hibernate versions where the setter signature changed; dialect-specific fetch-clause emulation setting the expression programmatically.
Related errors
- Table-expression (%s) did not match mutating table name - %s
- Property not among declared properties: " + property.getName
- First result cannot be negative
- Can't emulate fetch clause type:
- Could not find table group for: %s
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/3c31809d97e179e9.
Report an issue: GitHub.