hibernate/hibernate-orm · error · SqlTreeCreationException

Unable to interpret mapping-model type for Query parameter:

Error message

Unable to interpret mapping-model type for Query parameter: " + domainParam

What it means

Thrown as SqlTreeCreationException by SqmUtil.createValueBindings when the mapping-model Bindable type of a query parameter is null, so Hibernate cannot decide how to render and bind the parameter to JDBC. It occurs while translating/binding parameters at query execution: every JDBC parameter must resolve through the domain parameter's Bindable, and a null Bindable means the parameter appeared in a position where Hibernate could not infer a type and no explicit type was given.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmUtil.java:735

		}
		else if ( domainParamBinding.getBindType() instanceof BasicValuedMapping ) {
			return ( (BasicValuedMapping) domainParamBinding.getBindType() ).getJdbcMapping();
		}
		else {
			return null;
		}
	}

	private static void createValueBindings(
			JdbcParameterBindings jdbcParameterBindings,
			QueryParameterImplementor<?> domainParam,
			QueryParameterBinding<?> domainParamBinding,
			Bindable parameterType,
			JdbcParametersList jdbcParams,
			Object bindValue,
			SharedSessionContractImplementor session) {
		if ( parameterType == null ) {
			throw new SqlTreeCreationException( "Unable to interpret mapping-model type for Query parameter: " + domainParam );
		}
		final Bindable resolvedParameterType;
		if ( parameterType instanceof NullType ) {
			assert jdbcParams.size() == 1;
			final JdbcMappingContainer expressionType = jdbcParams.get( 0 ).getExpressionType();
			resolvedParameterType = expressionType == null
					? parameterType
					// If the parameter bind type is a NullType, which is a BasicValuedMapping,
					// the JdbcParameters' expression type must be a BasicValuedMapping, which is a Bindable
					: (Bindable) expressionType;
		}
		else {
			resolvedParameterType = parameterType;
		}
		final int offset =
				jdbcParameterBindings.registerParametersForEachJdbcValue(
						bindValue( resolvedParameterType, bindValue, session ),
						parameterType( domainParamBinding, resolvedParameterType ),

View on GitHub (pinned to fad1729dce)

Solutions

  1. Anchor the parameter to a typed path: 'where p.name = :p' gives Hibernate the type to infer
  2. Bind with an explicit type: query.setParameter("p", value, StringJavaType.INSTANCE) or the (name, value, Type) overload
  3. Cast the parameter in the query: 'where cast(:p as string) is null'
  4. Build the predicate dynamically and omit the parameter entirely when the value is null, instead of '(:p is null or ...)'

Example fix

// before
String hql = "from Person p where :p is null";
List<Person> r = session.createQuery(hql, Person.class).setParameter("p", maybeName).getResultList();
// after
String hql = "from Person p where p.name = :p";
List<Person> r = (maybeName == null)
        ? session.createQuery("from Person p", Person.class).getResultList()
        : session.createQuery(hql, Person.class).setParameter("p", maybeName, String.class).getResultList();
Defensive patterns

Strategy: validation

Validate before calling

static String optionalNameFilter(String hql, String paramName, String value) {
    // omit the parameter entirely when it has no typed anchor
    if (value == null) {
        return hql;
    }
    return hql + " and p.name = :" + paramName;
}

// when a bare parameter position is unavoidable, bind with an explicit type:
// query.setParameter("p", value, String.class);

Try / catch

try {
    return session.createQuery(hql, Person.class).setParameter("p", value, String.class).getResultList();
} catch (SqlTreeCreationException e) {
    // parameter type could not be resolved: log which parameter and rethrow as query config error
    throw new IllegalStateException("Query parameter without resolvable type in: " + hql, e);
}

Prevention

When it happens

Trigger: Parameters used in positions without type inference: 'where :p is null' (parameter not compared to any typed path), 'where :p1 = :p2' (parameter compared only to another parameter), binding null via setParameter without explicit type information; queries assembled dynamically where the optional-filter parameter keeps appearing after the anchoring predicate was removed.

Common situations: Optional-filter patterns like '(:name is null or p.name = :name)' written with the bare ':name is null' branch on databases/Hibernate versions where inference fails; dynamic query builders that keep parameters after dropping their typed anchor predicate; upgrading between Hibernate 6.x versions where parameter type inference rules changed.

Related errors


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