hibernate/hibernate-orm · error · IllegalStateException
Criteria parameter [{}] not known to be a parameter of the p
Error message
Criteria parameter [{}] not known to be a parameter of the processing tree What it means
getSqmParameter(JpaCriteriaParameter) looks the parameter up in jpaCriteriaParamResolutions, the map Hibernate builds when it first walks the criteria query tree. A missing entry means this JpaCriteriaParameter object was not present in the tree at compilation time - typically because the parameter was created for another query, or the tree was changed after the typed query was built.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/sql/spi/BaseSqmToSqlAstConverter.java:6838
private SqmParameter<?> getSqmParameter(SqmExpression<?> parameter) {
if ( parameter instanceof JpaCriteriaParameter<?> ) {
return getSqmParameter( (JpaCriteriaParameter<?>) parameter );
}
else if ( parameter instanceof SqmParameter<?> ) {
return (SqmParameter<?>) parameter;
}
return null;
}
private SqmParameter<?> getSqmParameter(JpaCriteriaParameter<?> expression) {
if ( jpaCriteriaParamResolutions == null ) {
throw new IllegalStateException( "No JpaCriteriaParameter resolutions registered" );
}
final var supplier = jpaCriteriaParamResolutions.get( expression );
if ( supplier == null ) {
throw new IllegalStateException( "Criteria parameter [" + expression + "] not known to be a parameter of the processing tree" );
}
return supplier;
}
@Override
public Object visitTuple(SqmTuple<?> sqmTuple) {
final var groupedExpressions = sqmTuple.getGroupedExpressions();
final int size = groupedExpressions.size();
final List<Expression> expressions = new ArrayList<>( size );
if ( resolveInferredType() instanceof ValueMapping valueMapping
&& valueMapping.getMappedType() instanceof EmbeddableMappingType embeddableMappingType ) {
for ( int i = 0; i < size; i++ ) {
final var attributeMapping = embeddableMappingType.getAttributeMapping( i );
inferrableTypeAccessStack.push( () -> attributeMapping );
try {
expressions.add( (Expression) groupedExpressions.get( i ).accept( this ) );
}
finally {View on GitHub (pinned to fad1729dce)
Solutions
- Create parameters fresh inside each query and bind with the exact same object
- Call createQuery(...) again after any mutation of the criteria tree, then bind parameters
- Prefer named parameters (setParameter("name", value)) over passing the ParameterExpression object
- Make shared predicate factories take the query's criteria builder and create parameters per call
Example fix
// before (static shared parameter)
private static final ParameterExpression<Long> ID = ...;
Query q1 = session.createQuery(cq1); q1.setParameter(ID, 1L);
// after (per-query parameter)
ParameterExpression<Long> id = cb.parameter(Long.class);
cq.where(cb.equal(root.get("id"), id));
Query q1 = session.createQuery(cq1); q1.setParameter(id, 1L); Defensive patterns
Strategy: validation
Validate before calling
// Before binding, confirm the parameter belongs to this query
if (!query.getParameters().contains(theParameter)) {
throw new IllegalStateException("Parameter does not belong to this query; create it with this query's CriteriaBuilder");
} Try / catch
try {
query.setParameter(theParam, value);
} catch (IllegalStateException e) {
if (e.getMessage() != null && e.getMessage().contains("not known to be a parameter")) {
// rebuild from criteria and rebind
Query<?> fresh = session.createQuery(cq);
fresh.setParameter(theParam, value);
return fresh.getResultList();
}
throw e;
} Prevention
- Never share ParameterExpression instances across queries
- Re-run createQuery after mutating a criteria tree before binding
- Prefer named parameters for stable binding across query rebuilds
When it happens
Trigger: Binding a ParameterExpression that belongs to a different criteria query instance; copying criteria fragments (predicates holding parameters) between queries; modifying the criteria tree after calling createQuery and then binding; reusing static ParameterExpression fields across many queries built from different CriteriaBuilder instances.
Common situations: Shared predicate libraries and static parameter constants; query DTOs that cache criteria pieces; Spring Data JPA custom repository fragments; code migrated from EclipseLink where cross-query parameter reuse happened to work.
Related errors
- Could not determine ValueMapping for SqmParameter: {}
- Informix does not support binary literals
- "Unsupported temporal type: " + temporalAccessor.getClass().
- Blobs may not be accessed after serialization
- Clobs may not be accessed after serialization
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/ba76f36111384839.
Report an issue: GitHub.