DATAJPA-1281 - Provide a better error message on mismatch between required and actual parameters.

The added assertion prevents the non descriptive IndexOutOfBoundsException and provides a more digestible message.

Original pull request: #255.
This commit is contained in:
Jens Schauder
2018-03-05 14:20:33 +01:00
committed by Mark Paluch
parent d6263d6483
commit 73870548f9
2 changed files with 31 additions and 2 deletions

View File

@@ -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),

View File

@@ -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<ParameterMetadataProvider.ParameterMetadata<?>> 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.");
}
}