hibernate/hibernate-orm · error · ExecutionException
JDBC parameter value not bound - %s
Error message
JDBC parameter value not bound - %s
What it means
When binding a PreparedStatement, Hibernate looks up the JdbcParameterBinding for each JdbcParameter in JdbcParameterBindings. If no binding was collected for that parameter instance during query translation/execution preparation, bindParameterValue throws ExecutionException('JDBC parameter value not bound - ' + parameter). The SQL contains a '?' whose parameter object has no entry in the binding map - a translation/binding pipeline mismatch, not a value the user forgot to set.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/sql/exec/internal/AbstractJdbcParameter.java:86
public void accept(SqlAstWalker sqlTreeWalker) {
sqlTreeWalker.visitParameter( this );
}
@Override
public JdbcMapping getSingleJdbcMapping() {
return jdbcMapping;
}
@Override
public void bindParameterValue(
PreparedStatement statement,
int startPosition,
JdbcParameterBindings jdbcParamBindings,
ExecutionContext executionContext) throws SQLException {
final var binding = jdbcParamBindings.getBinding( AbstractJdbcParameter.this );
if ( binding == null ) {
throw new ExecutionException( "JDBC parameter value not bound - " + this );
}
final var jdbcMapping = jdbcMapping( executionContext, binding );
bindParameterValue( jdbcMapping, statement, binding.getBindValue(), startPosition, executionContext );
}
private JdbcMapping jdbcMapping(ExecutionContext executionContext, JdbcParameterBinding binding) {
JdbcMapping jdbcMapping = binding.getBindType();
if ( jdbcMapping == null ) {
jdbcMapping = this.jdbcMapping;
}
// If the parameter type is not known from the context i.e. null or Object, infer it from the bind value
if ( jdbcMapping == null || jdbcMapping.getMappedJavaType().getJavaTypeClass() == Object.class ) {
jdbcMapping = guessBindType( executionContext, binding.getBindValue(), jdbcMapping );
}
View on GitHub (pinned to fad1729dce)
Solutions
- If a custom function/dialect creates JdbcParameters, register matching JdbcParameterBindings during rendering (mirror how standard functions do it)
- Clear or size down the query plan cache (hibernate.query.plan_cache_max_size, or restart) after upgrading Hibernate or swapping dialects to rule out stale plans
- Reproduce with a minimal entity/query and check/report the Hibernate JIRA (HHH) - this message typically indicates an internal bug
- As a workaround, disable the plan cache (hibernate.query.plan_cache_max_size=0) to force retranslation per execution
Defensive patterns
Strategy: try-catch
Try / catch
try {
return query.list();
} catch ( ExecutionException e ) {
if ( e.getMessage() != null && e.getMessage().startsWith( "JDBC parameter value not bound" ) ) {
// translation/binding mismatch: force retranslation, then retry once
session.getFactory().getQueryPlanCache().clear();
return session.createQuery( query.getQueryString(), query.getResultType() ).list();
}
throw e;
} Prevention
- Register JdbcParameterBindings for every JdbcParameter your custom function/translator creates
- Clear or size the query plan cache after upgrading Hibernate or changing dialects
- Report pure-mapping occurrences to the Hibernate JIRA (HHH) with a minimal reproducer
When it happens
Trigger: Executing a query whose SQL AST was built with JdbcParameter instances that never got registered in JdbcParameterBindingsImpl - typical of custom SqlAstTranslators, custom functions or dialect extensions that create parameters during rendering but skip binding registration; also cached query plans executed with bindings prepared against a different plan.
Common situations: Upgrading Hibernate with a stale query plan cache; custom dialect/function code creating parameters on one path and binding on another; concurrency bugs that reuse query plans across mismatched translations. When hit with vanilla mappings this message usually marks a Hibernate bug.
Related errors
- No JDBC mapping could be inferred for parameter - %s
- Could not resolve NativeQuery parameter type : `%s`
- JDBC parameter value not bound - %s
- JDBC driver does not support named parameters for setArray.
- Unable to locate JdbcValueDescriptor for column `%s`
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/7a1a6d9dbd3313fc.
Report an issue: GitHub.