diff --git a/src/main/java/org/springframework/data/jpa/repository/query/QueryParameterSetterFactory.java b/src/main/java/org/springframework/data/jpa/repository/query/QueryParameterSetterFactory.java index 778c4c858..f585a97d4 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/QueryParameterSetterFactory.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/QueryParameterSetterFactory.java @@ -268,13 +268,24 @@ abstract class QueryParameterSetterFactory { @Override public QueryParameterSetter create(ParameterBinding binding, DeclaredQuery declaredQuery) { - ParameterMetadata metadata = expressions.get(binding.getRequiredPosition() - 1); + int parameterIndex = binding.getRequiredPosition() - 1; + + Assert.isTrue( // + parameterIndex < expressions.size(), // + () -> String.format( // + "At least %s parameter(s) provided but only %s parameter(s) present in query.", // + binding.getRequiredPosition(), // + expressions.size() // + ) // + ); + + ParameterMetadata metadata = expressions.get(parameterIndex); if (metadata.isIsNullParameter()) { return QueryParameterSetter.NOOP; } - JpaParameter parameter = parameters.getBindableParameter(binding.getRequiredPosition() - 1); + JpaParameter parameter = parameters.getBindableParameter(parameterIndex); TemporalType temporalType = parameter.isTemporalParameter() ? parameter.getRequiredTemporalType() : null; return new NamedOrIndexedQueryParameterSetter(values -> getAndPrepare(parameter, metadata, values), diff --git a/src/test/java/org/springframework/data/jpa/repository/query/QueryParameterSetterFactoryUnitTests.java b/src/test/java/org/springframework/data/jpa/repository/query/QueryParameterSetterFactoryUnitTests.java index 527ba04f5..e40b785cf 100644 --- a/src/test/java/org/springframework/data/jpa/repository/query/QueryParameterSetterFactoryUnitTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/query/QueryParameterSetterFactoryUnitTests.java @@ -17,6 +17,8 @@ package org.springframework.data.jpa.repository.query; import static org.mockito.Mockito.*; +import java.util.Collections; +import java.util.List; import java.util.stream.Stream; import org.assertj.core.api.Assertions; @@ -61,4 +63,20 @@ public class QueryParameterSetterFactoryUnitTests { .withMessageContaining("@Param") // .withMessageContaining("-parameters"); } + + @Test // DATAJPA-1281 + public void exceptionWhenQueryContainsInsufficientAmountOfParameters() { + + // no parameter present in the criteria query + List> metadata = Collections.emptyList(); + QueryParameterSetterFactory setterFactory = QueryParameterSetterFactory.forCriteriaQuery(parameters, metadata); + + // one argument present in the method signature + when(binding.getRequiredPosition()).thenReturn(1); + + Assertions.assertThatExceptionOfType(IllegalArgumentException.class) // + .isThrownBy(() -> setterFactory.create(binding, DeclaredQuery.of("QueryStringWith :NamedParameter"))) // + .withMessage("At least 1 parameter(s) provided but only 0 parameter(s) present in query."); + + } }