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

  1. Check the actual type with getParameterMetadata().getQueryParameter(position).getParameterType() and request exactly that
  2. Request a supertype (Number/Object) when you only read the value
  3. For native queries, set the type explicitly at bind time: query.setParameter(1, value, Long.class), which also fixes later getParameter calls
  4. 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

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


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