hibernate/hibernate-orm · error · IllegalArgumentException
Type specified for parameter at position {position} is incom
Error message
Type specified for parameter at position {position} is incompatible ({parameterType.getName()} is not assignable to {type.getName()}) What it means
Positional twin of error 2368: getParameter(int position, Class<T> type) looks up the ordinal parameter via getParameterMetadata().getQueryParameter(position) and rejects the request when !type.isAssignableFrom(parameterType). The parameter's determined type (from query analysis) must be the requested type or a subtype; otherwise IllegalArgumentException with both class names is thrown before any result execution.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/internal/AbstractCommonQueryContract.java:912
public QueryParameterImplementor<?> getParameter(int position) {
session.checkOpen( false );
try {
return getParameterMetadata().getQueryParameter( position );
}
catch ( HibernateException e ) {
throw getExceptionConverter().convert( e );
}
}
@Override
@Nonnull
public <T> QueryParameterImplementor<T> getParameter(int position, @Nonnull Class<T> type) {
session.checkOpen( false );
try {
final var parameter = getParameterMetadata().getQueryParameter( position );
final var parameterType = parameter.getParameterType();
if ( !type.isAssignableFrom( parameterType ) ) {
throw new IllegalArgumentException(
"Type specified for parameter at position " + position + " 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
public <T> T getParameterValue(@Nonnull Parameter<T> param) {
session.checkOpen( false );
final var parameter = getParameterMetadata().resolve( param );
if ( parameter == null ) {View on GitHub (pinned to fad1729dce)
Solutions
- Check the actual type with getParameterMetadata().getQueryParameter(position).getParameterType() and request exactly that
- Request a supertype (Number/Object) when you only read the value
- For native queries, set the type explicitly at bind time: query.setParameter(1, value, Long.class), which also fixes later getParameter calls
- Align the expected type in helper code with the query's real inference (sum→Long etc.)
Example fix
// before QueryParameterImplementor<Integer> p = query.getParameter( 1, Integer.class ); // Long/LocalDate etc. not assignable to Integer // after QueryParameterImplementor<Long> p = query.getParameter( 1, Long.class );
Defensive patterns
Strategy: validation
Validate before calling
Class<?> actual = query.getParameterMetadata().getQueryParameter( position ).getParameterType(); if ( !expected.isAssignableFrom( actual ) ) throw new IllegalStateException( "Param " + position + " is " + actual + ", not " + expected ); QueryParameterImplementor<T> p = query.getParameter( position, expected );
Type guard
static <T> boolean parameterTypeMatches(
org.hibernate.query.Query<?> q, int position, Class<T> expected) {
Class<?> actual = q.getParameterMetadata().getQueryParameter( position ).getParameterType();
return expected.isAssignableFrom( actual );
} Prevention
- For native queries, always bind with an explicit type: query.setParameter(1, v, Long.class)
- Don't hardcode Integer/Date in generic accessors; derive from metadata
- Test typed accessors whenever the query string or mapping changes
When it happens
Trigger: query.getParameter(1, Integer.class) where parameter ?1 is bound/inferred as Long, LocalDate, or an enum. Reusing a typed accessor across queries whose positional parameters have different inferred types (native queries often infer differently than HQL). Generic repositories calling getParameter(position, expectedClass) from a per-entity type registry.
Common situations: Native queries where parameter types come from result-set mapping or are Object until bound; Java 8 Date vs java.time migrations; upgrading Hibernate and getting stricter/different parameter type inference.
Related errors
- Type specified for parameter named '{name}' is incompatible
- Received {arguments.length} arguments for {parameterCount} p
- The parameter [{param}] is not part of this Query
- The parameter at position{position} has no argument
- Null value not allowed for multi-valued parameter '?{positio
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/cdbb3f63eb8c8c26.
Report an issue: GitHub.