{"record":{"id":"8df160ab2a35e368","repo":"hibernate/hibernate-orm","slug":"can-t-render-expression-as-literal","errorCode":null,"errorMessage":"Can't render expression as literal: ","messagePattern":"Can't render expression as literal: ","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java","lineNumber":700,"sourceCode":"\t\t\texpression.accept( this );\n\t\t\treturn;\n\t\t}\n\t\telse if ( expression instanceof JdbcParameter parameter ) {\n\t\t\tif ( jdbcParameterBindings == null ) {\n\t\t\t\tthrow new IllegalArgumentException( \"Can't interpret expression because no parameter bindings are available\" );\n\t\t\t}\n\t\t\trenderAsLiteral( parameter, getParameterBindValue( parameter ) );\n\t\t\treturn;\n\t\t}\n\t\telse if ( expression instanceof SqmParameterInterpretation parameterInterpretation ) {\n\t\t\tif ( jdbcParameterBindings == null ) {\n\t\t\t\tthrow new IllegalArgumentException( \"Can't interpret expression because no parameter bindings are available\" );\n\t\t\t}\n\t\t\tfinal JdbcParameter parameter = (JdbcParameter) parameterInterpretation.getResolvedExpression();\n\t\t\trenderAsLiteral( parameter, getParameterBindValue( parameter ) );\n\t\t\treturn;\n\t\t}\n\t\tthrow new UnsupportedOperationException( \"Can't render expression as literal: \" + expression );\n\t}\n\n\tprotected Object getParameterBindValue(JdbcParameter parameter) {\n\t\tfinal JdbcParameterBinding binding;\n\t\tif ( parameter == getOffsetParameter() ) {\n\t\t\tbinding = new JdbcParameterBindingImpl( getIntegerType(), getLimit().getFirstRow() );\n\t\t}\n\t\telse if ( parameter == getLimitParameter() ) {\n\t\t\tbinding = new JdbcParameterBindingImpl( getIntegerType(), getLimit().getMaxRows() );\n\t\t}\n\t\telse {\n\t\t\tbinding = jdbcParameterBindings.getBinding( parameter );\n\t\t}\n\t\taddAppliedParameterBinding( parameter, binding );\n\t\treturn binding.getBindValue();\n\t}\n\n\tprotected Expression getLeftHandExpression(Predicate predicate) {","sourceCodeStart":682,"sourceCodeEnd":718,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java#L682-L718","documentation":"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'.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before — emulation must render the function as a literal and cannot\nList<Pricing> ps = session.createQuery(\n    \"select p from Pricing p where lower(p.currency) = :ccy\", Pricing.class).list();\n\n// after — bind a plain value computed in Java so only literals/parameters remain\nList<Pricing> ps = session.createQuery(\n    \"select p from Pricing p where p.currency = :ccy\", Pricing.class)\n    .setParameter(\"ccy\", \"EUR\").list();","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    query.list();\n} catch (UnsupportedOperationException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Can't render expression as literal\")) {\n        // expression cannot be rendered inline: replace with literal/parameter or use native SQL\n        rows = runNativeFallback();\n    } else { throw e; }\n}","preventionTips":["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."],"tags":["hibernate","orm","sql-translation","dialect-emulation","unsupported-operation"],"backgroundTag":"sql-expression-interpretation-unsupported","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}