diff --git a/pom.xml b/pom.xml
index f4eb82b8bb..e1944c4395 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.data
spring-data-mongodb-parent
- 4.2.0-SNAPSHOT
+ 4.2.x-4542-SNAPSHOT
pom
Spring Data MongoDB
diff --git a/spring-data-mongodb-benchmarks/pom.xml b/spring-data-mongodb-benchmarks/pom.xml
index 2de4b6b635..98278be747 100644
--- a/spring-data-mongodb-benchmarks/pom.xml
+++ b/spring-data-mongodb-benchmarks/pom.xml
@@ -7,7 +7,7 @@
org.springframework.data
spring-data-mongodb-parent
- 4.2.0-SNAPSHOT
+ 4.2.x-4542-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb-distribution/pom.xml b/spring-data-mongodb-distribution/pom.xml
index 41b81f9aa6..ee93704bbf 100644
--- a/spring-data-mongodb-distribution/pom.xml
+++ b/spring-data-mongodb-distribution/pom.xml
@@ -15,7 +15,7 @@
org.springframework.data
spring-data-mongodb-parent
- 4.2.0-SNAPSHOT
+ 4.2.x-4542-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml
index d7a9ddaa63..fcde832a09 100644
--- a/spring-data-mongodb/pom.xml
+++ b/spring-data-mongodb/pom.xml
@@ -13,7 +13,7 @@
org.springframework.data
spring-data-mongodb-parent
- 4.2.0-SNAPSHOT
+ 4.2.x-4542-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/CrudMethodMetadataPostProcessor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/CrudMethodMetadataPostProcessor.java
index 22992b7335..183f427cd7 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/CrudMethodMetadataPostProcessor.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/CrudMethodMetadataPostProcessor.java
@@ -89,9 +89,12 @@ static class CrudMethodMetadataPopulatingMethodInterceptor implements MethodInte
private final ConcurrentMap metadataCache = new ConcurrentHashMap<>();
private final Set implementations = new HashSet<>();
+ private final RepositoryInformation repositoryInformation;
CrudMethodMetadataPopulatingMethodInterceptor(RepositoryInformation repositoryInformation) {
+ this.repositoryInformation = repositoryInformation;
+
ReflectionUtils.doWithMethods(repositoryInformation.getRepositoryInterface(), implementations::add,
method -> !repositoryInformation.isQueryMethod(method));
}
@@ -140,7 +143,7 @@ public Object invoke(MethodInvocation invocation) throws Throwable {
if (methodMetadata == null) {
- methodMetadata = new DefaultCrudMethodMetadata(method);
+ methodMetadata = new DefaultCrudMethodMetadata(repositoryInformation.getRepositoryInterface(), method);
CrudMethodMetadata tmp = metadataCache.putIfAbsent(method, methodMetadata);
if (tmp != null) {
@@ -171,23 +174,24 @@ static class DefaultCrudMethodMetadata implements CrudMethodMetadata {
/**
* Creates a new {@link DefaultCrudMethodMetadata} for the given {@link Method}.
*
+ * @param repositoryInterface the target repository interface.
* @param method must not be {@literal null}.
*/
- DefaultCrudMethodMetadata(Method method) {
+ DefaultCrudMethodMetadata(Class> repositoryInterface, Method method) {
Assert.notNull(method, "Method must not be null");
- this.readPreference = findReadPreference(method);
+ this.readPreference = findReadPreference(repositoryInterface, method);
}
- private Optional findReadPreference(Method method) {
+ private Optional findReadPreference(Class> repositoryInterface, Method method) {
org.springframework.data.mongodb.repository.ReadPreference preference = AnnotatedElementUtils
.findMergedAnnotation(method, org.springframework.data.mongodb.repository.ReadPreference.class);
if (preference == null) {
- preference = AnnotatedElementUtils.findMergedAnnotation(method.getDeclaringClass(),
+ preference = AnnotatedElementUtils.findMergedAnnotation(repositoryInterface,
org.springframework.data.mongodb.repository.ReadPreference.class);
}
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/DefaultCrudMethodMetadataUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/DefaultCrudMethodMetadataUnitTests.java
new file mode 100644
index 0000000000..68e23ca9e2
--- /dev/null
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/DefaultCrudMethodMetadataUnitTests.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.data.mongodb.repository.support;
+
+import static org.assertj.core.api.Assertions.*;
+
+import java.util.Optional;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.data.mongodb.repository.Person;
+import org.springframework.data.mongodb.repository.ReadPreference;
+import org.springframework.data.mongodb.repository.support.CrudMethodMetadataPostProcessor.DefaultCrudMethodMetadata;
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.util.ReflectionUtils;
+
+/**
+ * @author Christoph Strobl
+ */
+class DefaultCrudMethodMetadataUnitTests {
+
+ @Test // GH-4542
+ void detectsReadPreferenceOnRepositoryInterface() {
+
+ DefaultCrudMethodMetadata metadata = new DefaultCrudMethodMetadata(ReadPreferenceAnnotated.class,
+ ReflectionUtils.findMethod(ReadPreferenceAnnotated.class, "findAll"));
+
+ assertThat(metadata.getReadPreference()).hasValue(com.mongodb.ReadPreference.primary());
+ }
+
+ @Test // GH-4542
+ void favorsReadPreferenceOfAnnotatedMethod() {
+
+ DefaultCrudMethodMetadata metadata = new DefaultCrudMethodMetadata(ReadPreferenceAnnotated.class,
+ ReflectionUtils.findMethod(ReadPreferenceAnnotated.class, "findById", Object.class));
+
+ assertThat(metadata.getReadPreference()).hasValue(com.mongodb.ReadPreference.secondary());
+ }
+
+ @ReadPreference("primary")
+ interface ReadPreferenceAnnotated extends CrudRepository {
+
+ @Override
+ @ReadPreference("secondary")
+ Optional findById(String s);
+ }
+}
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepositoryUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepositoryUnitTests.java
index 6e2d87b508..9981f72349 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepositoryUnitTests.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepositoryUnitTests.java
@@ -152,7 +152,7 @@ void shouldAddReadPreferenceToFindAllMethods(Consumer(entityInformation, mongoOperations);
repository.setRepositoryMethodMetadata(
- new DefaultCrudMethodMetadata(TestRepositoryWithReadPreference.class.getMethod("dummy")));
+ new DefaultCrudMethodMetadata(TestRepositoryWithReadPreference.class, TestRepositoryWithReadPreference.class.getMethod("dummy")));
findCall.accept(repository);
@@ -167,7 +167,7 @@ void shouldAddReadPreferenceToFindOne() throws NoSuchMethodException {
repository = new SimpleMongoRepository<>(entityInformation, mongoOperations);
repository.setRepositoryMethodMetadata(
- new DefaultCrudMethodMetadata(TestRepositoryWithReadPreference.class.getMethod("dummy")));
+ new DefaultCrudMethodMetadata(TestRepositoryWithReadPreference.class, TestRepositoryWithReadPreference.class.getMethod("dummy")));
repository.findOne(Example.of(new TestDummy()));
@@ -188,7 +188,7 @@ void shouldAddReadPreferenceToFluentFetchable() throws NoSuchMethodException {
repository = new SimpleMongoRepository<>(entityInformation, mongoOperations);
repository.setRepositoryMethodMetadata(
- new DefaultCrudMethodMetadata(TestRepositoryWithReadPreferenceMethod.class.getMethod("dummy")));
+ new DefaultCrudMethodMetadata(TestRepositoryWithReadPreferenceMethod.class, TestRepositoryWithReadPreferenceMethod.class.getMethod("dummy")));
repository.findBy(Example.of(new TestDummy()), FetchableFluentQuery::all);