{"record":{"id":"955b46c1c35dcee9","repo":"hibernate/hibernate-orm","slug":"can-t-interpret-expression-because-no-parameter-bi","errorCode":null,"errorMessage":"Can't interpret expression because no parameter bindings are available","messagePattern":"Can't interpret expression because no parameter bindings are available","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java","lineNumber":653,"sourceCode":"\t}\n\n\tprotected void setLimitParameter(JdbcParameter limitParameter) {\n\t\tthis.limitParameter = limitParameter;\n\t}\n\n\t@Override\n\tpublic <X> X getLiteralValue(Expression expression) {\n\t\treturn interpretExpression( expression, jdbcParameterBindings );\n\t}\n\n\t@SuppressWarnings(\"unchecked\")\n\tprotected <R> R interpretExpression(Expression expression, JdbcParameterBindings jdbcParameterBindings) {\n\t\tif ( expression instanceof Literal literal ) {\n\t\t\treturn (R) literal.getLiteralValue();\n\t\t}\n\t\telse if ( expression instanceof JdbcParameter jdbcParameter ) {\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\treturn (R) getParameterBindValue( jdbcParameter );\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\treturn (R) getParameterBindValue( (JdbcParameter) parameterInterpretation.getResolvedExpression() );\n\t\t}\n\t\telse if ( expression instanceof FunctionExpression functionExpression ) {\n\t\t\tif ( \"concat\".equals( functionExpression.getFunctionName() ) ) {\n\t\t\t\tfinal List<? extends SqlAstNode> arguments = functionExpression.getArguments();\n\t\t\t\tfinal StringBuilder sb = new StringBuilder();\n\t\t\t\tfor ( SqlAstNode argument : arguments ) {\n\t\t\t\t\tfinal Object argumentLiteral = interpretExpression( (Expression) argument, jdbcParameterBindings );\n\t\t\t\t\tif ( argumentLiteral == null ) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}","sourceCodeStart":635,"sourceCodeEnd":671,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java#L635-L671","documentation":"AbstractSqlAstTranslator.interpretExpression() must turn an expression into a concrete Java value; for JdbcParameter nodes it reads the current JdbcParameterBindings. When it is invoked while jdbcParameterBindings is null — typically via getLiteralValue() from places that need real values (dialects inlining limit/offset or function arguments like concat as literals, or integrator subclasses calling it outside the bound translation phase) — it throws IllegalArgumentException: the value simply cannot be known without bindings.","triggerScenarios":"A SQL AST parameter reaching a translation path that must interpret it as a literal while no JdbcParameterBindings were supplied: parameterized limit/offset on dialects requiring literal values, arguments of functions the translator folds locally, or a custom translator/dialect hook calling getLiteralValue() before bindings exist.","commonSituations":"Third-party dialects or translator customizations; native-image or query-rewriting integrations that render SQL before parameter binding; framework code caching Translator output (SQL strings) at a point where parameters are not yet bound.","solutions":["Ensure translation happens with parameter bindings available — bind all query parameters before executing/rendering","Avoid parameter markers in positions the dialect must inline as literals (e.g. literal limit/offset constants or literal function arguments)","In custom translator code, only call getLiteralValue()/interpretExpression() during the bound translation phase, and guard for null bindings","Upgrade Hibernate — inlining decisions around parameters change between 6.x minor releases"],"exampleFix":"// before (HQL)\nem.createQuery(\"select o from Order o order by o.id\")\n  .setFirstResult(offsetParam).setMaxResults(limitParam); // params reach literal-requiring path\n\n// after\nem.createQuery(\"select o from Order o order by o.id\")\n  .setFirstResult(200).setMaxResults(50); // concrete values inline cleanly","handlingStrategy":"validation","validationCode":"// integrator-side: only interpret expressions when bindings exist\nJdbcParameterBindings bindings = getJdbcParameterBindings();\nif (bindings == null) {\n    throw new IllegalStateException(\"bind parameters before interpreting expressions\");\n}\nreturn getLiteralValue(expression);","typeGuard":"boolean isInterpretable(Expression expr, JdbcParameterBindings bindings) {\n    return expr instanceof Literal || (isParameterLike(expr) && bindings != null);\n}","tryCatchPattern":"try {\n    return getLiteralValue(expression);\n}\ncatch (IllegalArgumentException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"no parameter bindings\")) {\n        // fall back: render as a JDBC parameter marker instead of a literal\n        renderAsParameterMarker(expression);\n    }\n    else throw e;\n}","preventionTips":["Bind all query parameters before execution; never render/translate SQL before binding","Use literal constants where a dialect must inline values (limits, folded function args)","In custom translator code, check for null bindings before calling getLiteralValue()"],"tags":["sql-ast","parameters","query-api","dialect"],"backgroundTag":"missing-parameter-bindings","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}