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

  1. Create parameters fresh inside each query and bind with the exact same object
  2. Call createQuery(...) again after any mutation of the criteria tree, then bind parameters
  3. Prefer named parameters (setParameter("name", value)) over passing the ParameterExpression object
  4. 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

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


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