hibernate/hibernate-orm · error · UnsupportedOperationException
Can't render expression as literal:
Error message
Can't render expression as literal:
What it means
The fall-through of renderExpressionAsLiteral: the expression is neither a Literal, a JdbcParameter, nor a SqmParameterInterpretation — e.g., a function call, CASE, arithmetic, or star expression — while a dialect emulation needs it as an inline SQL literal, so translation aborts with UnsupportedOperationException("Can't render expression as literal: " + expression). It is the rendering-side sibling of 'Can't interpret expression'.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java:700
expression.accept( this );
return;
}
else if ( expression instanceof JdbcParameter parameter ) {
if ( jdbcParameterBindings == null ) {
throw new IllegalArgumentException( "Can't interpret expression because no parameter bindings are available" );
}
renderAsLiteral( parameter, getParameterBindValue( parameter ) );
return;
}
else if ( expression instanceof SqmParameterInterpretation parameterInterpretation ) {
if ( jdbcParameterBindings == null ) {
throw new IllegalArgumentException( "Can't interpret expression because no parameter bindings are available" );
}
final JdbcParameter parameter = (JdbcParameter) parameterInterpretation.getResolvedExpression();
renderAsLiteral( parameter, getParameterBindValue( parameter ) );
return;
}
throw new UnsupportedOperationException( "Can't render expression as literal: " + expression );
}
protected Object getParameterBindValue(JdbcParameter parameter) {
final JdbcParameterBinding binding;
if ( parameter == getOffsetParameter() ) {
binding = new JdbcParameterBindingImpl( getIntegerType(), getLimit().getFirstRow() );
}
else if ( parameter == getLimitParameter() ) {
binding = new JdbcParameterBindingImpl( getIntegerType(), getLimit().getMaxRows() );
}
else {
binding = jdbcParameterBindings.getBinding( parameter );
}
addAppliedParameterBinding( parameter, binding );
return binding.getBindValue();
}
protected Expression getLeftHandExpression(Predicate predicate) {View on GitHub (pinned to fad1729dce)
Solutions
- Replace the expression with a literal value or a bound parameter (parameters are renderable when bindings exist; functions/CASE are not).
- Move the expression outside the emulated fragment or compute it in application code.
- Use a native SQL query for this statement.
- Upgrade hibernate-core — literal-rendering coverage differs per version and dialect.
Example fix
// before — emulation must render the function as a literal and cannot
List<Pricing> ps = session.createQuery(
"select p from Pricing p where lower(p.currency) = :ccy", Pricing.class).list();
// after — bind a plain value computed in Java so only literals/parameters remain
List<Pricing> ps = session.createQuery(
"select p from Pricing p where p.currency = :ccy", Pricing.class)
.setParameter("ccy", "EUR").list(); Defensive patterns
Strategy: try-catch
Try / catch
try {
query.list();
} catch (UnsupportedOperationException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Can't render expression as literal")) {
// expression cannot be rendered inline: replace with literal/parameter or use native SQL
rows = runNativeFallback();
} else { throw e; }
} Prevention
- Do not place functions, CASE, or arithmetic in positions a dialect may need to render as literals.
- Validate unusual query shapes against the weakest supported dialect in your test matrix.
- Keep a native-SQL escape hatch for statements that push dialect emulation limits.
When it happens
Trigger: An emulation that must write the value of an expression directly into SQL (renderExpressionAsLiteral) receives a non-literal, non-parameter expression — typically a function/CASE/arithmetic node placed where the dialect can only emit a literal.
Common situations: Expressions inside fragments a dialect emulates literally (limit clauses, CTE or set-operation emulations); queries portable on one DB but not another; Hibernate upgrades activating new literal-rendering paths; criteria dynamically building CASE expressions.
Related errors
- Can't interpret expression:
- removeTableGroupJoin not supported by %s
- Injection of parent instance into embeddable result is not p
- The Embeddable: %s parent initializer is neither an instance
- dynamic instantiation in a sub-query is unsupported
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/8df160ab2a35e368.
Report an issue: GitHub.