Skip to content

Commit e78e197

Browse files
christophstroblmp911de
authored andcommitted
Resolve @ReadPreference on actual repository interface.
Original pull request: #4545 Closes #4542
1 parent db86097 commit e78e197

File tree

3 files changed

+71
-8
lines changed

3 files changed

+71
-8
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/CrudMethodMetadataPostProcessor.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,12 @@ static class CrudMethodMetadataPopulatingMethodInterceptor implements MethodInte
8989

9090
private final ConcurrentMap<Method, CrudMethodMetadata> metadataCache = new ConcurrentHashMap<>();
9191
private final Set<Method> implementations = new HashSet<>();
92+
private final RepositoryInformation repositoryInformation;
9293

9394
CrudMethodMetadataPopulatingMethodInterceptor(RepositoryInformation repositoryInformation) {
9495

96+
this.repositoryInformation = repositoryInformation;
97+
9598
ReflectionUtils.doWithMethods(repositoryInformation.getRepositoryInterface(), implementations::add,
9699
method -> !repositoryInformation.isQueryMethod(method));
97100
}
@@ -140,7 +143,7 @@ public Object invoke(MethodInvocation invocation) throws Throwable {
140143

141144
if (methodMetadata == null) {
142145

143-
methodMetadata = new DefaultCrudMethodMetadata(method);
146+
methodMetadata = new DefaultCrudMethodMetadata(repositoryInformation.getRepositoryInterface(), method);
144147
CrudMethodMetadata tmp = metadataCache.putIfAbsent(method, methodMetadata);
145148

146149
if (tmp != null) {
@@ -171,23 +174,24 @@ static class DefaultCrudMethodMetadata implements CrudMethodMetadata {
171174
/**
172175
* Creates a new {@link DefaultCrudMethodMetadata} for the given {@link Method}.
173176
*
177+
* @param repositoryInterface the target repository interface.
174178
* @param method must not be {@literal null}.
175179
*/
176-
DefaultCrudMethodMetadata(Method method) {
180+
DefaultCrudMethodMetadata(Class<?> repositoryInterface, Method method) {
177181

178182
Assert.notNull(method, "Method must not be null");
179183

180-
this.readPreference = findReadPreference(method);
184+
this.readPreference = findReadPreference(repositoryInterface, method);
181185
}
182186

183-
private Optional<ReadPreference> findReadPreference(Method method) {
187+
private Optional<ReadPreference> findReadPreference(Class<?> repositoryInterface, Method method) {
184188

185189
org.springframework.data.mongodb.repository.ReadPreference preference = AnnotatedElementUtils
186190
.findMergedAnnotation(method, org.springframework.data.mongodb.repository.ReadPreference.class);
187191

188192
if (preference == null) {
189193

190-
preference = AnnotatedElementUtils.findMergedAnnotation(method.getDeclaringClass(),
194+
preference = AnnotatedElementUtils.findMergedAnnotation(repositoryInterface,
191195
org.springframework.data.mongodb.repository.ReadPreference.class);
192196
}
193197

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright 2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.mongodb.repository.support;
17+
18+
import static org.assertj.core.api.Assertions.*;
19+
20+
import java.util.Optional;
21+
22+
import org.junit.jupiter.api.Test;
23+
import org.springframework.data.mongodb.repository.Person;
24+
import org.springframework.data.mongodb.repository.ReadPreference;
25+
import org.springframework.data.mongodb.repository.support.CrudMethodMetadataPostProcessor.DefaultCrudMethodMetadata;
26+
import org.springframework.data.repository.CrudRepository;
27+
import org.springframework.util.ReflectionUtils;
28+
29+
/**
30+
* @author Christoph Strobl
31+
*/
32+
class DefaultCrudMethodMetadataUnitTests {
33+
34+
@Test // GH-4542
35+
void detectsReadPreferenceOnRepositoryInterface() {
36+
37+
DefaultCrudMethodMetadata metadata = new DefaultCrudMethodMetadata(ReadPreferenceAnnotated.class,
38+
ReflectionUtils.findMethod(ReadPreferenceAnnotated.class, "findAll"));
39+
40+
assertThat(metadata.getReadPreference()).hasValue(com.mongodb.ReadPreference.primary());
41+
}
42+
43+
@Test // GH-4542
44+
void favorsReadPreferenceOfAnnotatedMethod() {
45+
46+
DefaultCrudMethodMetadata metadata = new DefaultCrudMethodMetadata(ReadPreferenceAnnotated.class,
47+
ReflectionUtils.findMethod(ReadPreferenceAnnotated.class, "findById", Object.class));
48+
49+
assertThat(metadata.getReadPreference()).hasValue(com.mongodb.ReadPreference.secondary());
50+
}
51+
52+
@ReadPreference("primary")
53+
interface ReadPreferenceAnnotated extends CrudRepository<Person, String> {
54+
55+
@Override
56+
@ReadPreference("secondary")
57+
Optional<Person> findById(String s);
58+
}
59+
}

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepositoryUnitTests.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ void shouldAddReadPreferenceToFindAllMethods(Consumer<SimpleMongoRepository<Obje
152152

153153
repository = new SimpleMongoRepository<>(entityInformation, mongoOperations);
154154
repository.setRepositoryMethodMetadata(
155-
new DefaultCrudMethodMetadata(TestRepositoryWithReadPreference.class.getMethod("dummy")));
155+
new DefaultCrudMethodMetadata(TestRepositoryWithReadPreference.class, TestRepositoryWithReadPreference.class.getMethod("dummy")));
156156

157157
findCall.accept(repository);
158158

@@ -167,7 +167,7 @@ void shouldAddReadPreferenceToFindOne() throws NoSuchMethodException {
167167

168168
repository = new SimpleMongoRepository<>(entityInformation, mongoOperations);
169169
repository.setRepositoryMethodMetadata(
170-
new DefaultCrudMethodMetadata(TestRepositoryWithReadPreference.class.getMethod("dummy")));
170+
new DefaultCrudMethodMetadata(TestRepositoryWithReadPreference.class, TestRepositoryWithReadPreference.class.getMethod("dummy")));
171171

172172
repository.findOne(Example.of(new TestDummy()));
173173

@@ -188,7 +188,7 @@ void shouldAddReadPreferenceToFluentFetchable() throws NoSuchMethodException {
188188

189189
repository = new SimpleMongoRepository<>(entityInformation, mongoOperations);
190190
repository.setRepositoryMethodMetadata(
191-
new DefaultCrudMethodMetadata(TestRepositoryWithReadPreferenceMethod.class.getMethod("dummy")));
191+
new DefaultCrudMethodMetadata(TestRepositoryWithReadPreferenceMethod.class, TestRepositoryWithReadPreferenceMethod.class.getMethod("dummy")));
192192

193193
repository.findBy(Example.of(new TestDummy()), FetchableFluentQuery::all);
194194

0 commit comments

Comments
 (0)