hibernate/hibernate-orm · error · IllegalArgumentException

Received {arguments.length} arguments for {parameterCount} p

Error message

Received {arguments.length} arguments for {parameterCount} positional parameters

What it means

Thrown by setParameters(Object... arguments): it counts the query's ordinal parameters via getParameterMetadata().getOrdinalParameterLabels().size() and requires arguments.length to match exactly, before binding position i+1 from argument i. The message reports both counts ('Received N arguments for M positional parameters'). It is a strict arity check — extra or missing arguments are rejected up front rather than partially bound.

Source

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

			if ( multipleBinding( binding.getQueryParameter(), value ) ) {
				if ( value == null ) {
					throw new IllegalArgumentException( "Null value not allowed for multi-valued parameter '?" + position + "'" );
				}
				setParameterList( position, (Collection<?>) value );
			}
			else {
				binding.setBindValue( value, resolveJdbcParameterTypeIfNecessary() );
			}
		}
		return this;
	}

	@Override
	@Nonnull
	public CommonQueryContractImplementor setParameters(@Nonnull Object... arguments) {
		final int parameterCount = getParameterMetadata().getOrdinalParameterLabels().size();
		if ( arguments.length != parameterCount ) {
			throw new IllegalArgumentException(
					"Received " + arguments.length + " arguments for "
							+ parameterCount + " positional parameters"
			);
		}
		for ( int i = 0; i < arguments.length; i++ ) {
			setParameter( i + 1, arguments[i] );
		}
		return this;
	}

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

View on GitHub (pinned to fad1729dce)

Solutions

  1. Make argument count authoritative from metadata: build the array to length getParameterMetadata().getOrdinalParameterLabels().size() before calling setParameters
  2. Prefer per-position binding (setParameter(1, v1)) or named parameters so arity drift fails at a precise, readable location
  3. Add a unit test asserting arguments.length == expected positional count whenever the query string changes

Example fix

// before
query.setParameters( new Object[]{ customerId } );
// 'Received 1 arguments for 2 positional parameters'

// after
int n = query.getParameterMetadata().getOrdinalParameterLabels().size();
assert args.length == n;
query.setParameters( args );
Defensive patterns

Strategy: validation

Validate before calling

int expected = query.getParameterMetadata().getOrdinalParameterLabels().size();
if ( args.length != expected ) {
    throw new IllegalArgumentException( "Need " + expected + " args, got " + args.length );
}
query.setParameters( args );

Prevention

When it happens

Trigger: query.setParameters(1L, "NEW") on a query declaring three positional parameters (or one). Editing an HQL/native query to add/remove a '?' without updating the Object[] built by the caller. Mixing named parameters into the query — they are not counted as ordinal, so the argument count no longer matches. Varargs passthrough: setParameters(list.toArray()) where list size diverges.

Common situations: Query text maintained separately from binding code (property files, @Query annotations, SQL templates); version changes that alter parameter counting for native queries; copy-pasted DAO methods with one more argument than the query needs.

Related errors


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