Introduce Parameter.getRequiredName() method.

Add getRequiredName to shortcut parameter name discovery and fast-fail in cases where the parameter name is required.

Closes #3124
This commit is contained in:
Mark Paluch
2024-07-23 09:16:33 +02:00
parent 9ab34d8672
commit 71484159cf
2 changed files with 26 additions and 7 deletions

View File

@@ -24,6 +24,7 @@ import java.util.List;
import java.util.Optional;
import org.springframework.core.MethodParameter;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.core.ResolvableType;
import org.springframework.data.domain.Limit;
import org.springframework.data.domain.Pageable;
@@ -59,7 +60,8 @@ public class Parameter {
static {
List<Class<?>> types = new ArrayList<>(Arrays.asList(ScrollPosition.class, Pageable.class, Sort.class, Limit.class));
List<Class<?>> types = new ArrayList<>(
Arrays.asList(ScrollPosition.class, Pageable.class, Sort.class, Limit.class));
// consider Kotlin Coroutines Continuation a special parameter. That parameter is synthetic and should not get
// bound to any query.
@@ -153,23 +155,39 @@ public class Parameter {
}
/**
* Returns whether the parameter is annotated with {@link Param}.
* Returns whether the parameter is annotated with {@link Param} or has a method parameter name.
*
* @return
* @see Param
* @see ParameterNameDiscoverer
*/
public boolean isNamedParameter() {
return !isSpecialParameter() && getName().isPresent();
}
/**
* Returns the name of the parameter (through {@link Param} annotation).
* Returns the name of the parameter (through {@link Param} annotation or method parameter naming).
*
* @return
* @return the optional name of the parameter.
*/
public Optional<String> getName() {
return this.name.get();
}
/**
* Returns the required name of the parameter (through {@link Param} annotation or method parameter naming) or throws
* {@link IllegalStateException} if the parameter has no name.
*
* @return the required parameter name.
* @throws IllegalStateException if the parameter has no name.
* @since 3.4
*/
public String getRequiredName() {
return getName().orElseThrow(() -> new IllegalStateException("Parameter " + parameter
+ " is not named. For queries with named parameters you need to provide names for method parameters; Use @Param for query method parameters, or use the javac flag -parameters."));
}
/**
* Returns the type of the {@link Parameter}.
*

View File

@@ -128,12 +128,13 @@ class ParametersUnitTests {
getParametersFor("validWithPageableFirst", Pageable.class, String.class);
}
@Test // DATACMNS-731
@Test // DATACMNS-731, GH-3124
void detectsExplicitlyNamedParameter() throws Exception {
var parameter = getParametersFor("valid", String.class).getBindableParameter(0);
assertThat(parameter.getName()).isNotNull();
assertThat(parameter.getName()).isNotEmpty();
assertThat(parameter.getRequiredName()).isNotNull();
assertThat(parameter.isExplicitlyNamed()).isTrue();
}
@@ -145,7 +146,7 @@ class ParametersUnitTests {
var methodParameter = ReflectionTestUtils.getField(parameter, "parameter");
ReflectionTestUtils.setField(methodParameter, "parameterName", "name");
assertThat(parameter.getName()).isNotNull();
assertThat(parameter.getName()).isNotEmpty();
assertThat(parameter.isExplicitlyNamed()).isFalse();
}