From 42dadd89b437264fa80711f324e35ecedf24f814 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Fri, 29 Jul 2022 14:33:04 +0200 Subject: [PATCH] Use `CompletableFuture` instead of deprecated `ListenableFuture`. Closes #2669 --- src/main/asciidoc/repositories.adoc | 4 ---- .../repository-query-return-types-reference.adoc | 1 - .../util/QueryExecutionConverters.java | 16 +++++++--------- .../util/QueryExecutionConvertersUnitTests.java | 2 ++ .../util/NullableWrapperConvertersUnitTests.java | 3 +++ 5 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/main/asciidoc/repositories.adoc b/src/main/asciidoc/repositories.adoc index 870a37e0c..308e320db 100644 --- a/src/main/asciidoc/repositories.adoc +++ b/src/main/asciidoc/repositories.adoc @@ -873,13 +873,9 @@ Future findByFirstname(String firstname); <1> @Async CompletableFuture findOneByFirstname(String firstname); <2> - -@Async -ListenableFuture findOneByLastname(String lastname); <3> ---- <1> Use `java.util.concurrent.Future` as the return type. <2> Use a Java 8 `java.util.concurrent.CompletableFuture` as the return type. -<3> Use a `org.springframework.util.concurrent.ListenableFuture` as the return type. ==== [[repositories.create-instances]] diff --git a/src/main/asciidoc/repository-query-return-types-reference.adoc b/src/main/asciidoc/repository-query-return-types-reference.adoc index 730f777d1..a64027e21 100644 --- a/src/main/asciidoc/repository-query-return-types-reference.adoc +++ b/src/main/asciidoc/repository-query-return-types-reference.adoc @@ -30,7 +30,6 @@ Some store modules may define their own result wrapper types. |Vavr `Seq`, `List`, `Map`, `Set`|Vavr collection types. See <> for details. |`Future`|A `Future`. Expects a method to be annotated with `@Async` and requires Spring's asynchronous method execution capability to be enabled. |`CompletableFuture`|A Java 8 `CompletableFuture`. Expects a method to be annotated with `@Async` and requires Spring's asynchronous method execution capability to be enabled. -|`ListenableFuture`|A `org.springframework.util.concurrent.ListenableFuture`. Expects a method to be annotated with `@Async` and requires Spring's asynchronous method execution capability to be enabled. |`Slice`|A sized chunk of data with an indication of whether there is more data available. Requires a `Pageable` method parameter. |`Page`|A `Slice` with additional information, such as the total number of results. Requires a `Pageable` method parameter. |`GeoResult`|A result entry with additional information, such as the distance to a reference location. diff --git a/src/main/java/org/springframework/data/repository/util/QueryExecutionConverters.java b/src/main/java/org/springframework/data/repository/util/QueryExecutionConverters.java index e8a3216b0..ced249c9e 100644 --- a/src/main/java/org/springframework/data/repository/util/QueryExecutionConverters.java +++ b/src/main/java/org/springframework/data/repository/util/QueryExecutionConverters.java @@ -15,7 +15,6 @@ */ package org.springframework.data.repository.util; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -45,7 +44,6 @@ import org.springframework.data.util.NullableWrapperConverters; import org.springframework.data.util.StreamUtils; import org.springframework.data.util.Streamable; import org.springframework.data.util.TypeInformation; -import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; import org.springframework.scheduling.annotation.AsyncResult; import org.springframework.util.Assert; @@ -92,7 +90,9 @@ public abstract class QueryExecutionConverters { WRAPPER_TYPES.add(WrapperType.singleValue(Future.class)); UNWRAPPER_TYPES.add(WrapperType.singleValue(Future.class)); WRAPPER_TYPES.add(WrapperType.singleValue(ListenableFuture.class)); + WRAPPER_TYPES.add(WrapperType.singleValue(CompletableFuture.class)); UNWRAPPER_TYPES.add(WrapperType.singleValue(ListenableFuture.class)); + UNWRAPPER_TYPES.add(WrapperType.singleValue(CompletableFuture.class)); ALLOWED_PAGEABLE_TYPES.add(Slice.class); ALLOWED_PAGEABLE_TYPES.add(Page.class); @@ -102,9 +102,7 @@ public abstract class QueryExecutionConverters { UNWRAPPERS.addAll(CustomCollections.getUnwrappers()); - CustomCollections.getCustomTypes().stream() - .map(WrapperType::multiValue) - .forEach(WRAPPER_TYPES::add); + CustomCollections.getCustomTypes().stream().map(WrapperType::multiValue).forEach(WRAPPER_TYPES::add); CustomCollections.getPaginationReturnTypes().forEach(ALLOWED_PAGEABLE_TYPES::add); @@ -302,8 +300,7 @@ public abstract class QueryExecutionConverters { this.wrapperTypes = Collections.singleton(nullValue.getClass()); } - AbstractWrapperTypeConverter(Object nullValue, - Iterable> wrapperTypes) { + AbstractWrapperTypeConverter(Object nullValue, Iterable> wrapperTypes) { this.nullValue = nullValue; this.wrapperTypes = wrapperTypes; } @@ -345,13 +342,14 @@ public abstract class QueryExecutionConverters { * * @author Oliver Gierke */ + @Deprecated(since = "3.0") private static class NullableWrapperToFutureConverter extends AbstractWrapperTypeConverter { /** * Creates a new {@link NullableWrapperToFutureConverter} using the given {@link ConversionService}. */ NullableWrapperToFutureConverter() { - super(new AsyncResult<>(null), Arrays.asList(Future.class, ListenableFuture.class)); + super(new AsyncResult<>(null), List.of(ListenableFuture.class)); } @Override @@ -371,7 +369,7 @@ public abstract class QueryExecutionConverters { * Creates a new {@link NullableWrapperToCompletableFutureConverter} using the given {@link ConversionService}. */ NullableWrapperToCompletableFutureConverter() { - super(CompletableFuture.completedFuture(null)); + super(CompletableFuture.completedFuture(null), List.of(Future.class)); } @Override diff --git a/src/test/java/org/springframework/data/repository/util/QueryExecutionConvertersUnitTests.java b/src/test/java/org/springframework/data/repository/util/QueryExecutionConvertersUnitTests.java index bd8080e18..847e55465 100755 --- a/src/test/java/org/springframework/data/repository/util/QueryExecutionConvertersUnitTests.java +++ b/src/test/java/org/springframework/data/repository/util/QueryExecutionConvertersUnitTests.java @@ -75,6 +75,7 @@ class QueryExecutionConvertersUnitTests { assertThat(QueryExecutionConverters.supports(java.util.Optional.class)).isTrue(); assertThat(QueryExecutionConverters.supports(Future.class)).isTrue(); assertThat(QueryExecutionConverters.supports(ListenableFuture.class)).isTrue(); + assertThat(QueryExecutionConverters.supports(CompletableFuture.class)).isTrue(); assertThat(QueryExecutionConverters.supports(Option.class)).isTrue(); assertThat(QueryExecutionConverters.supports(io.vavr.control.Option.class)).isTrue(); } @@ -85,6 +86,7 @@ class QueryExecutionConvertersUnitTests { assertThat(QueryExecutionConverters.supportsUnwrapping(Optional.class)).isTrue(); assertThat(QueryExecutionConverters.supportsUnwrapping(java.util.Optional.class)).isTrue(); assertThat(QueryExecutionConverters.supportsUnwrapping(Future.class)).isTrue(); + assertThat(QueryExecutionConverters.supportsUnwrapping(CompletableFuture.class)).isTrue(); assertThat(QueryExecutionConverters.supportsUnwrapping(ListenableFuture.class)).isTrue(); assertThat(QueryExecutionConverters.supportsUnwrapping(Option.class)).isTrue(); } diff --git a/src/test/java/org/springframework/data/util/NullableWrapperConvertersUnitTests.java b/src/test/java/org/springframework/data/util/NullableWrapperConvertersUnitTests.java index 10a84f08e..2f2a8b943 100755 --- a/src/test/java/org/springframework/data/util/NullableWrapperConvertersUnitTests.java +++ b/src/test/java/org/springframework/data/util/NullableWrapperConvertersUnitTests.java @@ -19,6 +19,7 @@ import static org.assertj.core.api.Assertions.*; import scala.Option; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; import org.junit.jupiter.api.BeforeEach; @@ -54,6 +55,7 @@ class NullableWrapperConvertersUnitTests { assertThat(NullableWrapperConverters.supports(java.util.Optional.class)).isTrue(); assertThat(NullableWrapperConverters.supports(Future.class)).isFalse(); assertThat(NullableWrapperConverters.supports(ListenableFuture.class)).isFalse(); + assertThat(NullableWrapperConverters.supports(CompletableFuture.class)).isFalse(); assertThat(NullableWrapperConverters.supports(Option.class)).isTrue(); assertThat(NullableWrapperConverters.supports(io.vavr.control.Option.class)).isTrue(); } @@ -65,6 +67,7 @@ class NullableWrapperConvertersUnitTests { assertThat(NullableWrapperConverters.supportsUnwrapping(java.util.Optional.class)).isTrue(); assertThat(NullableWrapperConverters.supportsUnwrapping(Future.class)).isFalse(); assertThat(NullableWrapperConverters.supportsUnwrapping(ListenableFuture.class)).isFalse(); + assertThat(NullableWrapperConverters.supportsUnwrapping(CompletableFuture.class)).isFalse(); assertThat(NullableWrapperConverters.supportsUnwrapping(Option.class)).isTrue(); }