hibernate/hibernate-orm · error · QueryArgumentException
Argument to query parameter has an incompatible type
Error message
Argument to query parameter has an incompatible type
What it means
Thrown (QueryArgumentException) by setParameterValues(Object[] values, QueryParameterBinding<P> binding), reached via setParameterList(String name, Object[] values): when the binding already knows its type (getBindType() != null) and QueryArguments.areInstances(parameterType, values, nodeBuilder) finds the array elements are not instances of that type, the bind is rejected before setBindValues. The exception carries the expected Java type, the array's component type, and the offending array.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/internal/AbstractCommonQueryContract.java:1415
@Nonnull Collection<? extends P> values,
@Nonnull Type<P> type) {
locateBinding( name ).setBindValues( values, (BindableType<P>) type );
return this;
}
@Override
@Nonnull
public CommonQueryContractImplementor setParameterList(@Nonnull String name, @Nonnull Object[] values) {
final var binding = getQueryParameterBindings().getBinding( name );
setParameterValues( values, binding );
return this;
}
private <P> void setParameterValues(Object[] values, QueryParameterBinding<P> binding) {
final var parameterType = binding.getBindType();
if ( parameterType != null
&& !areInstances( parameterType, values, getNodeBuilder() ) ) {
throw new QueryArgumentException( "Argument to query parameter has an incompatible type",
parameterType.getJavaType(), values.getClass().getComponentType(), values );
}
@SuppressWarnings("unchecked") // safe, just checked
final var castArray = (P[]) values;
binding.setBindValues( List.of( castArray ) );
}
@Override
@Nonnull
public <P> CommonQueryContractImplementor setParameterList(
@Nonnull String name,
@Nonnull P[] values,
@Nonnull Class<P> javaType) {
final var javaDescriptor = getJavaType( javaType );
if ( javaDescriptor == null ) {
setParameterList( name, values );
}
else {View on GitHub (pinned to fad1729dce)
Solutions
- Convert the array to the parameter's exact component type first: Arrays.stream(strIds).map(Long::valueOf).toArray(Long[]::new)
- Check the expected type via the parameter metadata and write the converter against it rather than hardcoding
- For string-prone inputs, prefer setParameterList(name, List<Long>) after explicit conversion, or TypedParameterValue-free typed binds via setParameter(name, v, Long.class)
Example fix
// before
query.setParameterList( "ids", new String[]{ "1", "2" } ); // String[] into Long :ids
// after
Long[] ids = Arrays.stream( new String[]{ "1", "2" } ).map( Long::valueOf ).toArray( Long[]::new );
query.setParameterList( "ids", ids ); Defensive patterns
Strategy: validation
Validate before calling
Class<?> expected = query.getParameterMetadata().getQueryParameter( name ).getParameterType();
if ( !expected.isAssignableFrom( values.getClass().getComponentType() ) ) {
values = convert( values, expected ); // e.g. String[] -> Long[]
}
query.setParameterList( name, values ); Type guard
static <T> boolean arrayMatchesParam(Class<T> expected, Object[] arr) {
return expected.isAssignableFrom( arr.getClass().getComponentType() );
} Try / catch
try {
query.setParameterList( name, values );
} catch ( org.hibernate.query.QueryArgumentException e ) {
throw new IllegalArgumentException( "IN parameter '" + name + "' needs "
+ e.getExpectedType() + ", got " + (values == null ? "null" : values.getClass().getComponentType()), e );
} Prevention
- Convert web/JSON string arrays to the entity id type before binding
- Bind lists through setParameterList with the typed collection (List<Long>) rather than raw Object[]
- When changing an id type in the schema, update every IN-list call site in the same change
When it happens
Trigger: setParameterList("ids", new String[]{"1","2"}) where :ids was inferred as Long from 'o.id in :ids'. Passing Integer[] for a Long-typed parameter (Integer is not an instance of Long). Arrays of boxed values deserialized from JSON/web input (often String[]) forwarded straight into the bind.
Common situations: REST query-param lists arriving as String[] and bound without conversion; schema/type drift between entity attribute type and the frontend payload; refactoring entity id type from Integer to Long (or UUID) while callers still send the old array type.
Related errors
- Given TypedParameterValue is not assignable to given Paramet
- Type specified for parameter named '{name}' is incompatible
- Type specified for parameter at position {position} is incom
- Null value not allowed for multi-valued parameter ':{name}'
- 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/0ce640bcbe2221f6.
Report an issue: GitHub.