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
- Anchor the parameter to a typed path: 'where p.name = :p' gives Hibernate the type to infer
- Bind with an explicit type: query.setParameter("p", value, StringJavaType.INSTANCE) or the (name, value, Type) overload
- Cast the parameter in the query: 'where cast(:p as string) is null'
- 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
- Never leave a parameter in a position where it is not compared to a typed path
- Prefer building predicates dynamically over '(:p is null or ...)' patterns
- Always use the typed setParameter(name, value, type) overload for nullable or ambiguous binds
- Cast bare parameters: cast(:p as string)
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
- Could not determine ValueMapping for SqmParameter: {}
- JDBC driver does not support named parameters for setArray.
- Configuration property hibernate.jdbc.time_zone value [{}] i
- Default resolver threw exception
- "Unsupported temporal type: " + temporalAccessor.getClass().
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/134cc68ab9dc6a3d.
Report an issue: GitHub.