Skip to content

Commit 463cb47

Browse files
committed
MethodInvocationRecorder now supports traversing primitive properties.
We now return a default value for invocations of methods returning a primitive value to pass the AOP infrastructure's check for compatible values. Before, that barked at the null value returned for the invocation. Fixes spring-projects#2612.
1 parent 87b0498 commit 463cb47

File tree

2 files changed

+19
-5
lines changed

2 files changed

+19
-5
lines changed

src/main/java/org/springframework/data/util/MethodInvocationRecorder.java

+10-5
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.springframework.data.util;
1717

18+
import java.lang.reflect.Array;
1819
import java.lang.reflect.Method;
1920
import java.lang.reflect.Modifier;
2021
import java.util.Arrays;
@@ -158,7 +159,7 @@ private Optional<String> getPropertyPath(List<PropertyNameDetectionStrategy> str
158159

159160
private InvocationInformation registerInvocation(Method method, Class<?> proxyType) {
160161

161-
Recorded<?> create = Modifier.isFinal(proxyType.getModifiers()) ? new Unrecorded() : create(proxyType);
162+
Recorded<?> create = Modifier.isFinal(proxyType.getModifiers()) ? new Unrecorded(proxyType) : create(proxyType);
162163
InvocationInformation information = new InvocationInformation(create, method);
163164

164165
return this.information = information;
@@ -167,7 +168,7 @@ private InvocationInformation registerInvocation(Method method, Class<?> proxyTy
167168

168169
private static final class InvocationInformation {
169170

170-
private static final InvocationInformation NOT_INVOKED = new InvocationInformation(new Unrecorded(), null);
171+
private static final InvocationInformation NOT_INVOKED = new InvocationInformation(new Unrecorded(null), null);
171172

172173
private final Recorded<?> recorded;
173174
private final @Nullable Method invokedMethod;
@@ -251,7 +252,7 @@ public int hashCode() {
251252

252253
int result = ObjectUtils.nullSafeHashCode(recorded);
253254

254-
result = 31 * result + ObjectUtils.nullSafeHashCode(invokedMethod);
255+
result = (31 * result) + ObjectUtils.nullSafeHashCode(invokedMethod);
255256

256257
return result;
257258
}
@@ -386,8 +387,8 @@ public interface ToMapConverter<T, S> extends Function<T, Map<?, S>> {}
386387

387388
static class Unrecorded extends Recorded<Object> {
388389

389-
private Unrecorded() {
390-
super(null, null);
390+
private Unrecorded(@Nullable Class<?> type) {
391+
super(type == null ? null : type.isPrimitive() ? getDefaultValue(type) : null, null);
391392
}
392393

393394
/*
@@ -398,5 +399,9 @@ private Unrecorded() {
398399
public Optional<String> getPropertyPath(List<PropertyNameDetectionStrategy> strategies) {
399400
return Optional.empty();
400401
}
402+
403+
private static Object getDefaultValue(Class<?> clazz) {
404+
return Array.get(Array.newInstance(clazz, 1), 0);
405+
}
401406
}
402407
}

src/test/java/org/springframework/data/util/MethodInvocationRecorderUnitTests.java

+9
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,22 @@ void recordsInvocationOnInterface() {
8686
assertThat(recorder.record(Sample::getName).getPropertyPath()).hasValue("name");
8787
}
8888

89+
@Test // #2612
90+
void registersLookupForPrimitiveValue() {
91+
92+
Recorded<Foo> recorder = MethodInvocationRecorder.forProxyOf(Foo.class);
93+
94+
assertThat(recorder.record(Foo::getAge).getPropertyPath()).hasValue("age");
95+
}
96+
8997
static final class FinalType {}
9098

9199
@Getter
92100
static class Foo {
93101
Bar bar;
94102
Collection<Bar> bars;
95103
String name;
104+
int age;
96105
}
97106

98107
@Getter

0 commit comments

Comments
 (0)