Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit b2c3623

Browse files
committed
Resolve bridged method when projected PropertyDescriptor resolves to a bridge method.
We now skip synthetic bridge methods when resolving a PropertyDescriptor from a called interface method on the target type and resolve the bridged method. Closes #3215
1 parent 00409b3 commit b2c3623

File tree

2 files changed

+51
-4
lines changed

2 files changed

+51
-4
lines changed

‎src/main/java/org/springframework/data/projection/PropertyAccessingMethodInterceptor.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@
2020

2121
import org.aopalliance.intercept.MethodInterceptor;
2222
import org.aopalliance.intercept.MethodInvocation;
23+
2324
import org.springframework.beans.BeanUtils;
2425
import org.springframework.beans.BeanWrapper;
26+
import org.springframework.core.BridgeMethodResolver;
2527
import org.springframework.data.util.DirectFieldAccessFallbackBeanWrapper;
2628
import org.springframework.lang.Nullable;
2729
import org.springframework.util.Assert;
@@ -63,7 +65,8 @@ public Object invoke(@SuppressWarnings("null") MethodInvocation invocation) thro
6365
PropertyDescriptor descriptor = BeanUtils.findPropertyForMethod(method);
6466

6567
if (descriptor == null) {
66-
throw new IllegalStateException("Invoked method is not a property accessor");
68+
throw new IllegalStateException("Invoked method '%s' is not a property accessor on '%s'"
69+
.formatted(invocation.getMethod(), target.getWrappedClass().getName()));
6770
}
6871

6972
if (!isSetterMethod(method, descriptor)) {
@@ -84,9 +87,14 @@ private static boolean isSetterMethod(Method method, PropertyDescriptor descript
8487

8588
private static Method lookupTargetMethod(MethodInvocation invocation, Class<?> targetType) {
8689

87-
Method method = BeanUtils.findMethod(targetType, invocation.getMethod().getName(),
88-
invocation.getMethod().getParameterTypes());
90+
Method invokedMethod = invocation.getMethod();
91+
Method method = BeanUtils.findMethod(targetType, invokedMethod.getName(), invokedMethod.getParameterTypes());
92+
93+
if (method == null) {
94+
return invokedMethod;
95+
}
8996

90-
return method != null ? method : invocation.getMethod();
97+
return BridgeMethodResolver.findBridgedMethod(method);
9198
}
99+
92100
}

‎src/test/java/org/springframework/data/projection/PropertyAccessingMethodInterceptorUnitTests.java

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,19 @@ void detectsKotlinPropertiesWithLeadingIsOnTargetType() throws Throwable {
121121
assertThat(new PropertyAccessingMethodInterceptor(source).invoke(invocation)).isEqualTo(true);
122122
}
123123

124+
@Test // GH-3697
125+
void considersPropertyDescriptorsFromPackageProtectedSuperclass() throws Throwable {
126+
127+
var source = new SomeExposedClass();
128+
source.setFirstname("Walter");
129+
130+
when(invocation.getMethod()).thenReturn(Projection.class.getMethod("getFirstname"));
131+
132+
Object result = new PropertyAccessingMethodInterceptor(source).invoke(invocation);
133+
134+
assertThat(result).isEqualTo(source.getFirstname());
135+
}
136+
124137
static class Source {
125138

126139
String firstname;
@@ -138,4 +151,30 @@ interface Projection {
138151

139152
String someGarbage();
140153
}
154+
155+
static class SomeBaseclass {
156+
157+
private String firstname;
158+
159+
public String getFirstname() {
160+
return firstname;
161+
}
162+
163+
public void setFirstname(String firstname) {
164+
this.firstname = firstname;
165+
}
166+
}
167+
168+
public static class SomeExposedClass extends SomeBaseclass {
169+
170+
private String lastname;
171+
172+
public String getLastname() {
173+
return lastname;
174+
}
175+
176+
public void setLastname(String lastname) {
177+
this.lastname = lastname;
178+
}
179+
}
141180
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /