Skip to content

Commit 6894fcb

Browse files
committed
DATACMNS-1056 - Prevent QueryExecutionResultHander from rewrapping JDK 8 Optionals.
In case a repository method execution returns a JDK 8 Optional in the first place, the Optional instance had been wrapped into a third-party null-wrapper as is. We're now unwrapping the value held inside that optional and forward it to the value conversion.
1 parent 727ab83 commit 6894fcb

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

src/main/java/org/springframework/data/repository/core/support/QueryExecutionResultHandler.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014-2016 the original author or authors.
2+
* Copyright 2014-2017 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
1616
package org.springframework.data.repository.core.support;
1717

1818
import java.util.Map;
19+
import java.util.Optional;
1920

2021
import org.springframework.core.CollectionFactory;
2122
import org.springframework.core.convert.TypeDescriptor;
@@ -67,6 +68,8 @@ public Object postProcessInvocationResult(Object result, TypeDescriptor returnTy
6768
return result;
6869
}
6970

71+
result = unwrapOptional(result);
72+
7073
if (QueryExecutionConverters.supports(expectedReturnType)) {
7174

7275
TypeDescriptor targetType = TypeDescriptor.valueOf(expectedReturnType);
@@ -102,4 +105,19 @@ public Object postProcessInvocationResult(Object result, TypeDescriptor returnTy
102105
return null;
103106
}
104107

108+
/**
109+
* Unwraps the given value if it's a JDK 8 {@link Optional}.
110+
*
111+
* @param source can be {@literal null}.
112+
* @return
113+
*/
114+
@SuppressWarnings("unchecked")
115+
private static Object unwrapOptional(Object source) {
116+
117+
if (source == null) {
118+
return null;
119+
}
120+
121+
return Optional.class.isInstance(source) ? Optional.class.cast(source).orElse(null) : source;
122+
}
105123
}

src/test/java/org/springframework/data/repository/core/support/QueryExecutionResultHandlerUnitTests.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import static org.assertj.core.api.Assertions.*;
1919

20+
import javaslang.control.Option;
2021
import reactor.core.publisher.Flux;
2122
import reactor.core.publisher.Mono;
2223
import rx.Completable;
@@ -336,6 +337,17 @@ public void convertsReactorMonoIntoFlux() throws Exception {
336337
assertThat(flux.next().block()).isEqualTo(entity.block());
337338
}
338339

340+
@Test // DATACMNS-1056
341+
public void convertsOptionalToThirdPartyOption() throws Exception {
342+
343+
Entity value = new Entity();
344+
Optional<Entity> entity = Optional.of(value);
345+
346+
Object result = handler.postProcessInvocationResult(entity, TypeDescriptor.valueOf(Option.class));
347+
348+
assertThat(result).isInstanceOfSatisfying(Option.class, it -> assertThat(it.get()).isEqualTo(value));
349+
}
350+
339351
private static TypeDescriptor getTypeDescriptorFor(String methodName) throws Exception {
340352

341353
Method method = Sample.class.getMethod(methodName);

0 commit comments

Comments
 (0)