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

  1. Request the wider type: getParameter("total", Number.class) or the exact inferred type (Long for sum over integral columns, Double for floating point)
  2. Inspect the real type first: getParameterMetadata().getQueryParameter(name).getParameterType() and pass that class
  3. Force the wanted type in HQL: cast(o.price as Integer) or treat the parameter accordingly
  4. 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

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


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