hibernate/hibernate-orm · error · IllegalArgumentException
Type specified for parameter named '{name}' is incompatible
Error message
Type specified for parameter named '{name}' is incompatible ({parameterType.getName()} is not assignable to {type.getName()}) What it means
Thrown by getParameter(String name, Class<T> type) when the requested type is not a supertype of the parameter's determined type: the check is !type.isAssignableFrom(parameter.getParameterType()), so the parameter's runtime Java type must be assignable TO the class you request. The message prints both class names (actual first, requested second). A HibernateException raised inside is converted by the exception converter, but this incompatibility is a raw IllegalArgumentException.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/internal/AbstractCommonQueryContract.java:878
public QueryParameterImplementor<?> getParameter(@Nonnull String name) {
session.checkOpen( false );
try {
return getParameterMetadata().getQueryParameter( name );
}
catch ( HibernateException e ) {
throw getExceptionConverter().convert( e );
}
}
@Override
@Nonnull
public <T> QueryParameterImplementor<T> getParameter(@Nonnull String name, @Nonnull Class<T> type) {
session.checkOpen( false );
try {
final var parameter = getParameterMetadata().getQueryParameter( name );
final var parameterType = parameter.getParameterType();
if ( !type.isAssignableFrom( parameterType ) ) {
throw new IllegalArgumentException(
"Type specified for parameter named '" + name + "' is incompatible"
+ " (" + parameterType.getName() + " is not assignable to " + type.getName() + ")"
);
}
@SuppressWarnings("unchecked") // safe, just checked
var castParameter = (QueryParameterImplementor<T>) parameter;
return castParameter;
}
catch ( HibernateException e ) {
throw getExceptionConverter().convert( e );
}
}
@Override
@Nonnull
public QueryParameterImplementor<?> getParameter(int position) {
session.checkOpen( false );
try {View on GitHub (pinned to fad1729dce)
Solutions
- Request the wider type: getParameter("total", Number.class) or the exact inferred type (Long for sum over integral columns, Double for floating point)
- Inspect the real type first: getParameterMetadata().getQueryParameter(name).getParameterType() and pass that class
- Force the wanted type in HQL: cast(o.price as Integer) or treat the parameter accordingly
- Fix caller code that assumed Integer/Date and handle the actual type (e.g. .longValue())
Example fix
// before QueryParameterImplementor<Integer> p = query.getParameter( "total", Integer.class ); // 'java.lang.Long is not assignable to java.lang.Integer' // after QueryParameterImplementor<Long> p = query.getParameter( "total", Long.class ); // sum() infers Long
Defensive patterns
Strategy: validation
Validate before calling
Class<?> actual = query.getParameterMetadata().getQueryParameter( name ).getParameterType();
if ( !expected.isAssignableFrom( actual ) ) {
expected = (Class<T>) actual; // or fail fast with a clear message
}
QueryParameterImplementor<T> p = query.getParameter( name, expected ); Type guard
static <T> boolean parameterTypeMatches(
org.hibernate.query.Query<?> q, String name, Class<T> expected) {
Class<?> actual = q.getParameterMetadata().getQueryParameter( name ).getParameterType();
return expected.isAssignableFrom( actual );
} Prevention
- Prefer requesting the exact inferred type (sum→Long) or a supertype like Number
- Cache the parameter type per query template and reuse it for typed accessors
- Cover typed getParameter calls in tests so type-inference changes on upgrade are caught
When it happens
Trigger: query.getParameter("total", Integer.class) where the HQL 'select sum(o.price)' inferred the parameter/expression type as Long — Long is not assignable to Integer, so it fails. Requesting java.util.Date for a parameter bound as java.sql.Timestamp/LocalDate, or String for an enum-typed parameter. Generic helper code doing getParameter(name, expectedType) with a fixed type map.
Common situations: HQL function return types (sum → Long/Double/BigInteger depending on operand) after upgrading from Hibernate 5.x where type inference differed; temporal parameter types differing between java.util.Date and java.time types across a migration; helpers written against one schema reused on another.
Related errors
- Type specified for parameter at position {position} is incom
- Parameter %d of function '%s()' has type '%s', but argument
- Start and stop parameters of function '%s()' must be of the
- Step parameter of function '%s()' is of type '%s', but must
- Step parameter of function '%s()' is of type '%s', but must
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/96ad0ea1d793d627.
Report an issue: GitHub.