hibernate/hibernate-orm · error · IllegalArgumentException

Could not resolve jakarta.persistence.Parameter '{}' to org.

Error message

Could not resolve jakarta.persistence.Parameter '{}' to org.hibernate.query.QueryParameter

What it means

ParameterMetadataImpl.resolve(jakarta.persistence.Parameter) only accepts parameters that are Hibernate QueryParameterImplementor instances belonging to this query's own metadata. Any other jakarta.persistence.Parameter (from a different query, a different provider integration, or a criteria parameter not used to build this query) cannot be mapped, so it throws IllegalArgumentException with an UnknownParameterException cause.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/query/internal/ParameterMetadataImpl.java:230

	public boolean hasAnyMatching(Predicate<QueryParameterImplementor<?>> filter) {
		for ( var queryParameter : queryParameters.keySet() ) {
			if ( filter.test( queryParameter ) ) {
				return true;
			}
		}

		return false;
	}

	@Override
	public <P> QueryParameterImplementor<P> resolve(Parameter<P> param) {
		if ( param instanceof QueryParameterImplementor<P> parameterImplementor ) {
			return parameterImplementor;
		}

		final String errorMessage =
				"Could not resolve jakarta.persistence.Parameter '" + param + "' to org.hibernate.query.QueryParameter";
		throw new IllegalArgumentException(
				errorMessage,
				new UnknownParameterException( errorMessage )
		);
	}


	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Named parameter handling

	@Override
	public boolean hasNamedParameters() {
		return queryParametersByName != null && !queryParametersByName.isEmpty();
	}

	@Override
	public Set<String> getNamedParameterNames() {
		return queryParametersByName == null ? emptySet() : queryParametersByName.keySet();
	}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Bind by name or position instead: setParameter("status", value) or setParameter(1, value).
  2. Fetch the Parameter from the same query you execute: query.getParameter("status").
  3. For criteria queries, bind through the same CriteriaQuery instance the ParameterExpression was used in.

Example fix

// before
Parameter<?> param = otherQuery.getParameter("status");
thisQuery.setParameter(param, "ACTIVE"); // throws: not a parameter of this query

// after
thisQuery.setParameter("status", "ACTIVE");
// or
thisQuery.setParameter(thisQuery.getParameter("status"), "ACTIVE");
Defensive patterns

Strategy: validation

Validate before calling

static boolean isParameterOf(jakarta.persistence.Query q, jakarta.persistence.Parameter<?> p) {
    return q.getParameters().contains(p);
}

Type guard

static boolean isHibernateQueryParameter(jakarta.persistence.Parameter<?> p) {
    return p instanceof org.hibernate.query.QueryParameter;
}

Prevention

When it happens

Trigger: Calling query.setParameter(param, value) where param was obtained from a different query object (another createQuery call), or passing a CriteriaBuilder ParameterExpression that was not part of building this particular query. Internally, ParameterMetadata.resolve() is the throwing path.

Common situations: Generic repository layers that cache Parameter objects statically or in request scope; reusing one ParameterExpression across several criteria queries; code ported from environments where Parameter references were shared freely.

Related errors


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