hibernate/hibernate-orm · error · IllegalArgumentException

Null value not allowed for multi-valued parameter ':{name}'

Error message

Null value not allowed for multi-valued parameter ':{name}'

What it means

Intended guard in setParameter(String name, Object value): when the parameter allows multi-valued binding (IN-expansion) and multipleBinding(...) is true, a null value is rejected with IllegalArgumentException before attempting setParameterList(name, (Collection) value), because a null cannot be cast to Collection nor expanded. Caveat grounded in the source: multipleBinding() at line 1031 requires value instanceof Collection, so a literal null makes it return false and currently flows into the single-value binding path — this branch is effectively defensive/dead in this exact version but represents the rule 'null is not a valid value for a multi-valued parameter'.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/query/internal/AbstractCommonQueryContract.java:1070

		return getTypeConfiguration().getBasicTypeForJavaType( valueClass ) != null;
	}

	protected <P> QueryParameterImplementor<P> getQueryParameter(QueryParameterImplementor<P> parameter) {
		return parameter;
	}

	@Override
	@Nonnull
	public CommonQueryContractImplementor setParameter(@Nonnull String name, @Nullable Object value) {
		session.checkOpen( false );
		if ( value instanceof TypedParameterValue<?> typedParameterValue ) {
			setTypedParameter( name, typedParameterValue );
		}
		else {
			final var binding = getQueryParameterBindings().getBinding( name );
			if ( multipleBinding( binding.getQueryParameter(), value ) ) {
				if ( value == null ) {
					throw new IllegalArgumentException( "Null value not allowed for multi-valued parameter ':" + name + "'" );
				}
				setParameterList( name, (Collection<?>) value );
			}
			else {
				binding.setBindValue( value, resolveJdbcParameterTypeIfNecessary() );
			}
		}
		return this;
	}

	@Override
	@Nonnull
	public <P> CommonQueryContractImplementor setParameter(
			@Nonnull String name,
			@Nullable P value,
			@Nonnull Class<P> javaType) {
		final var javaDescriptor = getJavaType( javaType );
		if ( javaDescriptor == null ) {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Never pass null for an IN-list parameter — pass List.of() or restructure the query
  2. When the list is optional, build the query dynamically (Criteria API or two HQL variants) so the IN clause is omitted entirely rather than bound to null
  3. Use setParameterList(name, emptyList) semantics via an empty collection when the predicate is absent

Example fix

// before
List<Long> ids = filter == null ? null : filter.getIds();
query.setParameter( "ids", ids ); // null for multi-valued :ids

// after
List<Long> ids = filter == null ? List.of() : filter.getIds();
query.setParameterList( "ids", ids );
Defensive patterns

Strategy: validation

Validate before calling

if ( "ids".equals( name ) ) {
    Collection<?> safe = value == null ? List.of() : ( (Collection<?>) value );
    query.setParameterList( name, safe );
} else {
    query.setParameter( name, value );
}

Type guard

static boolean isMultiValuedParam(org.hibernate.query.Query<?> q, String name) {
    return q.getParameterMetadata().getQueryParameter( name ).allowsMultiValuedBinding();
}

Prevention

When it happens

Trigger: The guarded scenario: query.setParameter("ids", null) where the query contains 'o.id in :ids' and the parameter allows multi-valued binding. Also any subclass/override that widens multipleBinding to treat null as multi-valued will surface this message directly.

Common situations: Optional IN filters in dynamic search screens: when no checkboxes are selected, null is passed instead of an empty collection; Optional.map(...).orElse(null) pipelines feeding setParameter.

Related errors


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