diff --git a/src/main/java/org/springframework/data/repository/core/RepositoryCreationException.java b/src/main/java/org/springframework/data/repository/core/RepositoryCreationException.java index 2e64b1a05..4b071524f 100644 --- a/src/main/java/org/springframework/data/repository/core/RepositoryCreationException.java +++ b/src/main/java/org/springframework/data/repository/core/RepositoryCreationException.java @@ -15,6 +15,8 @@ */ package org.springframework.data.repository.core; +import org.jspecify.annotations.Nullable; + import org.springframework.dao.InvalidDataAccessApiUsageException; /** @@ -34,7 +36,7 @@ public class RepositoryCreationException extends InvalidDataAccessApiUsageExcept * @param msg the detail message. * @param repositoryInterface the repository interface. */ - public RepositoryCreationException(String msg, Class repositoryInterface) { + public RepositoryCreationException(@Nullable String msg, Class repositoryInterface) { super(msg); this.repositoryInterface = repositoryInterface; } @@ -46,7 +48,7 @@ public class RepositoryCreationException extends InvalidDataAccessApiUsageExcept * @param cause the root cause from the data access API in use. * @param repositoryInterface the repository interface. */ - public RepositoryCreationException(String msg, Throwable cause, Class repositoryInterface) { + public RepositoryCreationException(@Nullable String msg, @Nullable Throwable cause, Class repositoryInterface) { super(msg, cause); this.repositoryInterface = repositoryInterface; } @@ -54,4 +56,5 @@ public class RepositoryCreationException extends InvalidDataAccessApiUsageExcept public Class getRepositoryInterface() { return repositoryInterface; } + } diff --git a/src/main/java/org/springframework/data/repository/query/QueryCreationException.java b/src/main/java/org/springframework/data/repository/query/QueryCreationException.java index 474218f9d..7e7c3750f 100644 --- a/src/main/java/org/springframework/data/repository/query/QueryCreationException.java +++ b/src/main/java/org/springframework/data/repository/query/QueryCreationException.java @@ -17,6 +17,9 @@ package org.springframework.data.repository.query; import java.io.Serial; import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.Arrays; +import java.util.stream.Collectors; import org.jspecify.annotations.Nullable; @@ -31,7 +34,6 @@ import org.springframework.data.repository.core.RepositoryCreationException; public final class QueryCreationException extends RepositoryCreationException { private static final @Serial long serialVersionUID = -1238456123580L; - private static final String MESSAGE_TEMPLATE = "Could not create query for method [%s]; Could not find property '%s' on domain class '%s'"; private final Method method; @@ -81,7 +83,8 @@ public final class QueryCreationException extends RepositoryCreationException { public static QueryCreationException invalidProperty(QueryMethod method, String propertyName) { return new QueryCreationException( - String.format(MESSAGE_TEMPLATE, method, propertyName, method.getDomainClass().getName()), method); + "Could not find property '%s' on domain class '%s'".formatted(propertyName, method.getDomainClass().getName()), + method); } /** @@ -92,7 +95,7 @@ public final class QueryCreationException extends RepositoryCreationException { * @return the {@link QueryCreationException}. */ public static QueryCreationException create(QueryMethod method, String message) { - return new QueryCreationException(createMessage(message, method.getMethod()), method); + return new QueryCreationException(message, method); } /** @@ -134,13 +137,10 @@ public final class QueryCreationException extends RepositoryCreationException { */ public static QueryCreationException create(@Nullable String message, @Nullable Throwable cause, Class repositoryInterface, Method method) { - return new QueryCreationException(createMessage(message, method), + return new QueryCreationException(message, cause, repositoryInterface, method); } - private static String createMessage(@Nullable String message, Method method) { - return String.format("Could not create query for [%s]; Reason: %s", method, message); - } /** * @return the method causing the exception. @@ -150,4 +150,19 @@ public final class QueryCreationException extends RepositoryCreationException { return method; } + @Override + public String getLocalizedMessage() { + + StringBuilder sb = new StringBuilder(); + sb.append(method.getDeclaringClass().getSimpleName()).append('.'); + sb.append(method.getName()); + + sb.append(method.getName()); + sb.append(Arrays.stream(method.getParameterTypes()) // + .map(Type::getTypeName) // + .collect(Collectors.joining(",", "(", ")"))); + + return "Cannot create query for method [%s]; %s".formatted(sb.toString(), getMessage()); + } + } diff --git a/src/test/java/org/springframework/data/repository/core/support/RepositoryFactorySupportUnitTests.java b/src/test/java/org/springframework/data/repository/core/support/RepositoryFactorySupportUnitTests.java index 43b602bcc..f54b6d40b 100755 --- a/src/test/java/org/springframework/data/repository/core/support/RepositoryFactorySupportUnitTests.java +++ b/src/test/java/org/springframework/data/repository/core/support/RepositoryFactorySupportUnitTests.java @@ -539,7 +539,7 @@ class RepositoryFactorySupportUnitTests { }; assertThatThrownBy(() -> factory.getRepository(WithQueryMethodUsingInvalidProperty.class)) - .isInstanceOf(QueryCreationException.class).hasMessageContaining("findAllByName") + .isInstanceOf(QueryCreationException.class) .hasMessageContaining("No property 'name' found for type 'Object'"); }