diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveMongoQueryMethod.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveMongoQueryMethod.java index 391157e35..fdd6773b6 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveMongoQueryMethod.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveMongoQueryMethod.java @@ -34,6 +34,7 @@ import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.util.ReactiveWrapperConverters; import org.springframework.data.repository.util.ReactiveWrappers; import org.springframework.data.util.ClassTypeInformation; +import org.springframework.data.util.Lazy; import org.springframework.data.util.TypeInformation; import org.springframework.util.ClassUtils; @@ -50,6 +51,7 @@ public class ReactiveMongoQueryMethod extends MongoQueryMethod { private static final ClassTypeInformation SLICE_TYPE = ClassTypeInformation.from(Slice.class); private final Method method; + private final Lazy isCollectionQuery; /** * Creates a new {@link ReactiveMongoQueryMethod} from the given {@link Method}. @@ -92,6 +94,8 @@ public class ReactiveMongoQueryMethod extends MongoQueryMethod { } this.method = method; + this.isCollectionQuery = Lazy.of(() -> !(isPageQuery() || isSliceQuery()) + && ReactiveWrappers.isMultiValueType(metadata.getReturnType(method).getType())); } /* @@ -109,7 +113,7 @@ public class ReactiveMongoQueryMethod extends MongoQueryMethod { */ @Override public boolean isCollectionQuery() { - return !(isPageQuery() || isSliceQuery()) && ReactiveWrappers.isMultiValueType(method.getReturnType()); + return isCollectionQuery.get(); } /* diff --git a/spring-data-mongodb/src/test/kotlin/org/springframework/data/mongodb/repository/query/ReactiveMongoQueryMethodCoroutineUnitTests.kt b/spring-data-mongodb/src/test/kotlin/org/springframework/data/mongodb/repository/query/ReactiveMongoQueryMethodCoroutineUnitTests.kt new file mode 100644 index 000000000..ea77b86e9 --- /dev/null +++ b/spring-data-mongodb/src/test/kotlin/org/springframework/data/mongodb/repository/query/ReactiveMongoQueryMethodCoroutineUnitTests.kt @@ -0,0 +1,61 @@ +/* + * Copyright 2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.mongodb.repository.query + +import kotlinx.coroutines.flow.Flow +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import org.springframework.data.mongodb.core.mapping.MongoMappingContext +import org.springframework.data.mongodb.repository.Person +import org.springframework.data.projection.SpelAwareProxyProjectionFactory +import org.springframework.data.repository.core.support.DefaultRepositoryMetadata +import org.springframework.data.repository.kotlin.CoroutineCrudRepository +import kotlin.coroutines.Continuation + +/** + * Unit tests for [ReactiveMongoQueryMethod] using Coroutine repositories. + * + * @author Mark Paluch + */ +class ReactiveMongoQueryMethodCoroutineUnitTests { + + val projectionFactory = SpelAwareProxyProjectionFactory() + + interface PersonRepository : CoroutineCrudRepository { + + suspend fun findSuspendAllByName(): Flow + + fun findAllByName(): Flow + } + + @Test // DATAMONGO-2562 + internal fun `should consider methods returning Flow as collection queries`() { + + val method = PersonRepository::class.java.getMethod("findAllByName") + val queryMethod = ReactiveMongoQueryMethod(method, DefaultRepositoryMetadata(PersonRepository::class.java), projectionFactory, MongoMappingContext()) + + assertThat(queryMethod.isCollectionQuery).isTrue() + } + + @Test // DATAMONGO-2562 + internal fun `should consider suspended methods returning Flow as collection queries`() { + + val method = PersonRepository::class.java.getMethod("findSuspendAllByName", Continuation::class.java) + val queryMethod = ReactiveMongoQueryMethod(method, DefaultRepositoryMetadata(PersonRepository::class.java), projectionFactory, MongoMappingContext()) + + assertThat(queryMethod.isCollectionQuery).isTrue() + } +}