hibernate/hibernate-orm · error · UnsupportedOperationException

Can't interpret expression:

Error message

Can't interpret expression: 

What it means

Thrown from AbstractSqlAstTranslator.interpretExpression while SQL is being generated, when a dialect emulation needs the concrete Java value of an expression (constant folding). The interpreter only handles Literal, bound JdbcParameter / SqmParameterInterpretation, and exactly one function, 'concat'; every other node type (arithmetic, CASE, most function calls, subqueries) falls through to 'throw new UnsupportedOperationException("Can't interpret expression: " + expression)'. The message appends the expression's toString(), which tells you which node could not be folded.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java:677

				throw new IllegalArgumentException( "Can't interpret expression because no parameter bindings are available" );
			}
			return (R) getParameterBindValue( (JdbcParameter) parameterInterpretation.getResolvedExpression() );
		}
		else if ( expression instanceof FunctionExpression functionExpression ) {
			if ( "concat".equals( functionExpression.getFunctionName() ) ) {
				final List<? extends SqlAstNode> arguments = functionExpression.getArguments();
				final StringBuilder sb = new StringBuilder();
				for ( SqlAstNode argument : arguments ) {
					final Object argumentLiteral = interpretExpression( (Expression) argument, jdbcParameterBindings );
					if ( argumentLiteral == null ) {
						return null;
					}
					sb.append( argumentLiteral );
				}
				return (R) sb.toString();
			}
		}
		throw new UnsupportedOperationException( "Can't interpret expression: " + expression );
	}

	protected void renderExpressionAsLiteral(Expression expression, JdbcParameterBindings jdbcParameterBindings) {
		if ( expression instanceof Literal ) {
			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" );
			}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Rewrite the HQL/JPQL so the offending position holds a literal or plain column instead of a function/CASE/arithmetic expression (compute the value in Java and bind it as a parameter that the emulation can resolve).
  2. Move the expression out of the emulated fragment (e.g., out of the ORDER BY / FETCH / emulated predicate) so no interpretation is needed.
  3. Run the statement as a native SQL query (createNativeQuery) where the dialect emulation path is bypassed.
  4. Upgrade hibernate-core — the set of foldable expressions and which dialects need folding changes between minor versions.
  5. If you maintain a custom dialect, override interpretExpression in your SqlAstTranslator subclass to handle the node type.

Example fix

// before — dialect emulation must interpret the CASE expression and fails
List<Employee> es = session.createQuery(
    "select e from Employee e order by case when e.alias is null then e.name else e.alias end",
    Employee.class).list();

// after — do the folding in Java and bind the result so only literals/parameters remain
List<Employee> es = session.createQuery(
    "select e from Employee e where e.name = :effectiveName",
    Employee.class).setParameter("effectiveName", effective).list();
Defensive patterns

Strategy: try-catch

Try / catch

try {
    List<Employee> rows = query.list();
} catch (org.hibernate.query.IllegalQueryOperationException | UnsupportedOperationException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Can't interpret expression")) {
        // dialect cannot constant-fold this expression: fall back to native SQL or simplify the query
        log.warn("Unsupported expression for dialect emulation: {}", e.getMessage());
        rows = runNativeFallback();
    } else { throw e; }
}

Prevention

When it happens

Trigger: Executing a query on a dialect whose translator must inline real values during rendering (limit/offset inlining, function or predicate emulations that call getLiteralValue()/interpretExpression), where the expression in that position is anything other than a literal, a bound parameter, or a concat() tree — e.g. coalesce()/substring()/CASE/arithmetic inside the emulated fragment.

Common situations: Combining pagination or dialect-specific emulations with expressions the translator cannot fold; upgrading hibernate-core and hitting a newly active emulation path; custom dialects overriding interpretExpression; HQL that works on PostgreSQL but fails on H2/SQL Server/Oracle because only the latter's translator needs the value.

Related errors


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