diff --git a/pom.xml b/pom.xml index a43ca5f89b..2c19dcc919 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-commons - 3.0.0-SNAPSHOT + 3.0.0-2537-split-pagingandsortingrep-SNAPSHOT Spring Data Core diff --git a/src/main/asciidoc/repositories.adoc b/src/main/asciidoc/repositories.adoc index d1ab4600c8..e6b75117fc 100644 --- a/src/main/asciidoc/repositories.adoc +++ b/src/main/asciidoc/repositories.adoc @@ -58,13 +58,13 @@ public interface CrudRepository extends Repository { NOTE: We also provide persistence technology-specific abstractions, such as `JpaRepository` or `MongoRepository`. Those interfaces extend `CrudRepository` and expose the capabilities of the underlying persistence technology in addition to the rather generic persistence technology-agnostic interfaces such as `CrudRepository`. -On top of the `CrudRepository`, there is a https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/repository/PagingAndSortingRepository.html[`PagingAndSortingRepository`] abstraction that adds additional methods to ease paginated access to entities: +Additional to the `CrudRepository`, there is a https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/repository/PagingAndSortingRepository.html[`PagingAndSortingRepository`] abstraction that adds additional methods to ease paginated access to entities: .`PagingAndSortingRepository` interface ==== [source,java] ---- -public interface PagingAndSortingRepository extends CrudRepository { +public interface PagingAndSortingRepository { Iterable findAll(Sort sort); @@ -210,17 +210,35 @@ The sections that follow explain each step in detail: To define a repository interface, you first need to define a domain class-specific repository interface. The interface must extend `Repository` and be typed to the domain class and an ID type. -If you want to expose CRUD methods for that domain type, extend `CrudRepository` instead of `Repository`. +If you want to expose CRUD methods for that domain type, you may extend `CrudRepository`, or one of its variants instead of `Repository`. [[repositories.definition-tuning]] === Fine-tuning Repository Definition -Typically, your repository interface extends `Repository`, `CrudRepository`, or `PagingAndSortingRepository`. -Alternatively, if you do not want to extend Spring Data interfaces, you can also annotate your repository interface with `@RepositoryDefinition`. -Extending `CrudRepository` exposes a complete set of methods to manipulate your entities. -If you prefer to be selective about the methods being exposed, copy the methods you want to expose from `CrudRepository` into your domain repository. +There are a few variants how you can get started with your repository interface. -NOTE: Doing so lets you define your own abstractions on top of the provided Spring Data Repositories functionality. +The typical approach is to extend `CrudRepository`, which gives you methods for CRUD functionality. +CRUD stands for Create, Read, Update, Delete. +With version 3.0 we also introduced `ListCrudRepository` which is very similar to the `CrudRepository` but for those methods that return multiple entities it returns a `List` instead of an `Iterable` which you might find easier to use. + +If you are using a reactive store you might choose `ReactiveCrudRepository`, or `RxJava3CrudRepository` depending on which reactive framework you are using. + +If you are using Kotlin you might pick `CoroutineCrudRepository` which utilizes Kotlin's coroutines. + +Additional you can extend `PagingAndSortingRepository`, `ReactiveSortingRepository`, `RxJava3SortingRepository`, or `CoroutineSortingRepository` if you need methods that allow to specify a `Sort` abstraction or in the first case a `Pageable` abstraction. +Note that the various sorting repositories no longer extended their respective CRUD repository as they did in Spring Data Versions pre 3.0. +Therefore, you need to extend both interfaces if you want functionality of both. + +If you do not want to extend Spring Data interfaces, you can also annotate your repository interface with `@RepositoryDefinition`. +Extending one of the CRUD repository interfaces exposes a complete set of methods to manipulate your entities. +If you prefer to be selective about the methods being exposed, copy the methods you want to expose from the CRUD repository into your domain repository. +When doing so, you may change the return type of methods. +Spring Data will honor the return type if possible. +For example, for methods returning multiple entities you may choose `Iterable`, `List`, `Collection` or a VAVR list. + +If many repositories in your application should have the same set of methods you can define your own base interface to inherit from. +Such an interface must be annotated with `@NoRepositoryBean`. +This prevents Spring Data to try to create an instance of it directly and failing because it can't determine the entity for that repository, since it still contains a generic type variable. The following example shows how to selectively expose CRUD methods (`findById` and `save`, in this case): diff --git a/src/main/java/org/springframework/data/repository/PagingAndSortingRepository.java b/src/main/java/org/springframework/data/repository/PagingAndSortingRepository.java index 8f557d4a07..2b07b3c6b6 100644 --- a/src/main/java/org/springframework/data/repository/PagingAndSortingRepository.java +++ b/src/main/java/org/springframework/data/repository/PagingAndSortingRepository.java @@ -20,16 +20,19 @@ import org.springframework.data.domain.Sort; /** - * Extension of {@link CrudRepository} to provide additional methods to retrieve entities using the pagination and - * sorting abstraction. + * Repository fragment to provide methods to retrieve entities using the pagination and sorting abstraction. In many + * cases this will be combined with {@link CrudRepository} or similar or with manually added methods to provide CRUD + * functionality. * * @author Oliver Gierke + * @author Jens Schauder * @see Sort * @see Pageable * @see Page + * @see CrudRepository */ @NoRepositoryBean -public interface PagingAndSortingRepository extends CrudRepository { +public interface PagingAndSortingRepository extends Repository { /** * Returns all entities sorted by the given options. diff --git a/src/main/java/org/springframework/data/repository/reactive/ReactiveSortingRepository.java b/src/main/java/org/springframework/data/repository/reactive/ReactiveSortingRepository.java index 38e316d426..7ec08e63ae 100644 --- a/src/main/java/org/springframework/data/repository/reactive/ReactiveSortingRepository.java +++ b/src/main/java/org/springframework/data/repository/reactive/ReactiveSortingRepository.java @@ -20,20 +20,24 @@ import org.springframework.data.domain.Sort; import org.springframework.data.repository.NoRepositoryBean; +import org.springframework.data.repository.Repository; /** - * Extension of {@link ReactiveCrudRepository} to provide additional methods to retrieve entities using the sorting - * abstraction. + * Repository fragment to provide methods to retrieve entities using the sorting abstraction. In many cases it + * should be combined with {@link ReactiveCrudRepository} or a similar repository interface in order to add CRUD + * functionality. * * @author Mark Paluch * @author Christoph Strobl + * @author Jens Schauder * @since 2.0 * @see Sort * @see Mono * @see Flux + * @see ReactiveCrudRepository */ @NoRepositoryBean -public interface ReactiveSortingRepository extends ReactiveCrudRepository { +public interface ReactiveSortingRepository extends Repository { /** * Returns all entities sorted by the given options. diff --git a/src/main/java/org/springframework/data/repository/reactive/RxJava3SortingRepository.java b/src/main/java/org/springframework/data/repository/reactive/RxJava3SortingRepository.java index d2f069c67b..bae5dbd1c7 100644 --- a/src/main/java/org/springframework/data/repository/reactive/RxJava3SortingRepository.java +++ b/src/main/java/org/springframework/data/repository/reactive/RxJava3SortingRepository.java @@ -19,18 +19,21 @@ import org.springframework.data.domain.Sort; import org.springframework.data.repository.NoRepositoryBean; +import org.springframework.data.repository.Repository; /** - * Extension of {@link RxJava3CrudRepository} to provide additional methods to retrieve entities using the sorting - * abstraction. - * + * Repository fragment to provide methods to retrieve entities using the sorting abstraction. In many cases this + * should be combined with {@link RxJava3CrudRepository} or a similar interface to provide CRUD functionality. + * * @author Mark Paluch + * @author Jens Schauder * @since 2.4 * @see Sort * @see Flowable + * @see RxJava3CrudRepository */ @NoRepositoryBean -public interface RxJava3SortingRepository extends RxJava3CrudRepository { +public interface RxJava3SortingRepository extends Repository { /** * Returns all entities sorted by the given options. diff --git a/src/main/java/org/springframework/data/repository/support/DefaultRepositoryInvokerFactory.java b/src/main/java/org/springframework/data/repository/support/DefaultRepositoryInvokerFactory.java index bdd9195e52..c27e785d48 100644 --- a/src/main/java/org/springframework/data/repository/support/DefaultRepositoryInvokerFactory.java +++ b/src/main/java/org/springframework/data/repository/support/DefaultRepositoryInvokerFactory.java @@ -35,6 +35,7 @@ * * @author Oliver Gierke * @author Christoph Strobl + * @author Jens Schauder * @since 1.10 */ public class DefaultRepositoryInvokerFactory implements RepositoryInvokerFactory { @@ -93,7 +94,7 @@ private RepositoryInvoker prepareInvokers(Class domainType) { @SuppressWarnings("unchecked") protected RepositoryInvoker createInvoker(RepositoryInformation information, Object repository) { - if (repository instanceof PagingAndSortingRepository) { + if (repository instanceof PagingAndSortingRepository && repository instanceof CrudRepository) { return new PagingAndSortingRepositoryInvoker((PagingAndSortingRepository) repository, information, conversionService); } else if (repository instanceof CrudRepository) { diff --git a/src/main/java/org/springframework/data/repository/support/PagingAndSortingRepositoryInvoker.java b/src/main/java/org/springframework/data/repository/support/PagingAndSortingRepositoryInvoker.java index 738722119e..a2cc9505f2 100644 --- a/src/main/java/org/springframework/data/repository/support/PagingAndSortingRepositoryInvoker.java +++ b/src/main/java/org/springframework/data/repository/support/PagingAndSortingRepositoryInvoker.java @@ -21,6 +21,7 @@ import org.springframework.core.convert.ConversionService; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; +import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.core.RepositoryMetadata; @@ -29,6 +30,7 @@ * avoid reflection overhead introduced by the superclass. * * @author Oliver Gierke + * @author Jens Schauder * @since 1.10 */ class PagingAndSortingRepositoryInvoker extends CrudRepositoryInvoker { @@ -47,7 +49,7 @@ class PagingAndSortingRepositoryInvoker extends CrudRepositoryInvoker { public PagingAndSortingRepositoryInvoker(PagingAndSortingRepository repository, RepositoryMetadata metadata, ConversionService conversionService) { - super(repository, metadata, conversionService); + super((CrudRepository) repository, metadata, conversionService); var crudMethods = metadata.getCrudMethods(); diff --git a/src/main/kotlin/org/springframework/data/repository/kotlin/CoroutineSortingRepository.kt b/src/main/kotlin/org/springframework/data/repository/kotlin/CoroutineSortingRepository.kt index fd80d4e080..c588b9e419 100644 --- a/src/main/kotlin/org/springframework/data/repository/kotlin/CoroutineSortingRepository.kt +++ b/src/main/kotlin/org/springframework/data/repository/kotlin/CoroutineSortingRepository.kt @@ -18,18 +18,23 @@ package org.springframework.data.repository.kotlin import kotlinx.coroutines.flow.Flow import org.springframework.data.domain.Sort import org.springframework.data.repository.NoRepositoryBean +import org.springframework.data.repository.Repository /** - * Extension of [CoroutineCrudRepository] to provide additional methods to retrieve entities using the sorting + * Repository fragment to provide methods to retrieve entities using the sorting * abstraction. * + * In many cases this should be combined with [CoroutineCrudRepository] or similar or manually added methods to provide CRUD functionality. + * * @author Mark Paluch + * @author Jens Schauder * @since 2.3 * @see Flow * @see Sort + * @see CoroutineCrudRepository */ @NoRepositoryBean -interface CoroutineSortingRepository : CoroutineCrudRepository { +interface CoroutineSortingRepository : Repository { /** * Returns all entities sorted by the given options. diff --git a/src/test/java/org/springframework/data/repository/core/support/AbstractRepositoryMetadataUnitTests.java b/src/test/java/org/springframework/data/repository/core/support/AbstractRepositoryMetadataUnitTests.java index d10c609288..af126cc367 100755 --- a/src/test/java/org/springframework/data/repository/core/support/AbstractRepositoryMetadataUnitTests.java +++ b/src/test/java/org/springframework/data/repository/core/support/AbstractRepositoryMetadataUnitTests.java @@ -27,6 +27,7 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.querydsl.User; +import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.Repository; import org.springframework.data.repository.core.RepositoryMetadata; @@ -95,7 +96,7 @@ void handlesGenericTypeInReturnedCollectionCorrectly() throws SecurityException, @Test // DATACMNS-471 void detectsArrayReturnTypeCorrectly() throws Exception { - RepositoryMetadata metadata = new DefaultRepositoryMetadata(PagedRepository.class); + RepositoryMetadata metadata = new DefaultRepositoryMetadata(CompletePageableAndSortingRepository.class); var method = PagedRepository.class.getMethod("returnsArray"); assertThat(metadata.getReturnedDomainClass(method)).isEqualTo(User.class); @@ -169,4 +170,8 @@ abstract class Container implements Iterable {} interface ContainerRepository extends Repository { Container someMethod(); } + + interface CompletePageableAndSortingRepository extends PagingAndSortingRepository { + } + } diff --git a/src/test/java/org/springframework/data/repository/core/support/DefaultCrudMethodsUnitTests.java b/src/test/java/org/springframework/data/repository/core/support/DefaultCrudMethodsUnitTests.java index b88bfbebbc..13b4c338a7 100755 --- a/src/test/java/org/springframework/data/repository/core/support/DefaultCrudMethodsUnitTests.java +++ b/src/test/java/org/springframework/data/repository/core/support/DefaultCrudMethodsUnitTests.java @@ -197,7 +197,7 @@ interface Domain {} interface DomainCrudRepository extends CrudRepository {} - interface DomainPagingAndSortingRepository extends PagingAndSortingRepository {} + interface DomainPagingAndSortingRepository extends PagingAndSortingRepository, CrudRepository {} interface RepositoryWithCustomSave extends Repository { diff --git a/src/test/java/org/springframework/data/repository/core/support/DefaultRepositoryInformationUnitTests.java b/src/test/java/org/springframework/data/repository/core/support/DefaultRepositoryInformationUnitTests.java index d1584fa1ea..2261e64a8a 100755 --- a/src/test/java/org/springframework/data/repository/core/support/DefaultRepositoryInformationUnitTests.java +++ b/src/test/java/org/springframework/data/repository/core/support/DefaultRepositoryInformationUnitTests.java @@ -111,27 +111,11 @@ void considersIntermediateMethodsAsFinderMethods() { assertThat(information.hasCustomMethod()).isFalse(); } - @Test - void discoversIntermediateMethodsAsBackingMethods() throws NoSuchMethodException, SecurityException { - - var metadata = new DefaultRepositoryMetadata(CustomRepository.class); - var information = new DefaultRepositoryInformation(metadata, - PagingAndSortingRepository.class, RepositoryComposition.empty()); - - var method = CustomRepository.class.getMethod("findAll", Pageable.class); - assertThat(information.isBaseClassMethod(method)).isTrue(); - - method = getMethodFrom(CustomRepository.class, "existsById"); - - assertThat(information.isBaseClassMethod(method)).isTrue(); - assertThat(information.getQueryMethods()).isEmpty(); - } - @Test // DATACMNS-151 void doesNotConsiderManuallyDefinedSaveMethodAQueryMethod() { RepositoryMetadata metadata = new DefaultRepositoryMetadata(CustomRepository.class); - RepositoryInformation information = new DefaultRepositoryInformation(metadata, PagingAndSortingRepository.class, + RepositoryInformation information = new DefaultRepositoryInformation(metadata, CompletePageableAndSortingRepository.class, RepositoryComposition.empty()); assertThat(information.getQueryMethods()).isEmpty(); @@ -427,4 +411,8 @@ public Sample save(Sample entity) { return entity; } } + + interface CompletePageableAndSortingRepository extends CrudRepository, PagingAndSortingRepository { + } + } diff --git a/src/test/java/org/springframework/data/repository/core/support/ReactiveRepositoryInformationUnitTests.java b/src/test/java/org/springframework/data/repository/core/support/ReactiveRepositoryInformationUnitTests.java index 44f45229a9..59944a3bc1 100644 --- a/src/test/java/org/springframework/data/repository/core/support/ReactiveRepositoryInformationUnitTests.java +++ b/src/test/java/org/springframework/data/repository/core/support/ReactiveRepositoryInformationUnitTests.java @@ -66,7 +66,7 @@ void discoversRxJava3MethodWithConvertibleArguments() throws Exception { @Test // DATACMNS-836 void discoversMethodAssignableArguments() throws Exception { - var reference = extractTargetMethodFromRepository(ReactiveSortingRepository.class, "saveAll", Publisher.class); + var reference = extractTargetMethodFromRepository(ReactiveCrudRepository.class, "saveAll", Publisher.class); assertThat(reference.getDeclaringClass()).isEqualTo(ReactiveCrudRepository.class); assertThat(reference.getName()).isEqualTo("saveAll"); diff --git a/src/test/java/org/springframework/data/repository/core/support/ReactiveWrapperRepositoryFactorySupportUnitTests.java b/src/test/java/org/springframework/data/repository/core/support/ReactiveWrapperRepositoryFactorySupportUnitTests.java index 2601c9a257..d4cc3d2b00 100644 --- a/src/test/java/org/springframework/data/repository/core/support/ReactiveWrapperRepositoryFactorySupportUnitTests.java +++ b/src/test/java/org/springframework/data/repository/core/support/ReactiveWrapperRepositoryFactorySupportUnitTests.java @@ -20,6 +20,7 @@ import io.reactivex.rxjava3.core.Completable; import io.reactivex.rxjava3.core.Maybe; import io.reactivex.rxjava3.core.Single; +import org.springframework.data.repository.reactive.ReactiveCrudRepository; import reactor.core.publisher.Mono; import java.io.Serializable; @@ -47,7 +48,7 @@ class ReactiveWrapperRepositoryFactorySupportUnitTests { DummyRepositoryFactory factory; - @Mock ReactiveSortingRepository backingRepo; + @Mock ReactiveCrudRepository backingRepo; @Mock ObjectRepositoryCustom customImplementation; @BeforeEach diff --git a/src/test/java/org/springframework/data/repository/core/support/RepositoryFactorySupportUnitTests.java b/src/test/java/org/springframework/data/repository/core/support/RepositoryFactorySupportUnitTests.java index 923583d241..89ae8788db 100755 --- a/src/test/java/org/springframework/data/repository/core/support/RepositoryFactorySupportUnitTests.java +++ b/src/test/java/org/springframework/data/repository/core/support/RepositoryFactorySupportUnitTests.java @@ -51,6 +51,7 @@ import org.springframework.data.domain.Sort; import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.querydsl.QuerydslPredicateExecutor; +import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.Repository; import org.springframework.data.repository.RepositoryDefinition; @@ -90,7 +91,7 @@ class RepositoryFactorySupportUnitTests { DummyRepositoryFactory factory; - @Mock PagingAndSortingRepository backingRepo; + @Mock CrudRepository backingRepo; @Mock ObjectRepositoryCustom customImplementation; @Mock MyQueryCreationListener listener; @@ -167,12 +168,11 @@ void invokesCustomMethodCompositionMethodIfItRedeclaresACRUDOne() { void createsRepositoryInstanceWithCustomIntermediateRepository() { var repository = factory.getRepository(CustomRepository.class); - Pageable pageable = PageRequest.of(0, 10); - when(backingRepo.findAll(pageable)).thenReturn(new PageImpl<>(Collections.emptyList())); - repository.findAll(pageable); + when(backingRepo.findAll()).thenReturn(new PageImpl<>(Collections.emptyList())); + repository.findAll(); - verify(backingRepo, times(1)).findAll(pageable); + verify(backingRepo, times(1)).findAll(); } @Test diff --git a/src/test/java/org/springframework/data/repository/support/CrudRepositoryInvokerUnitTests.java b/src/test/java/org/springframework/data/repository/support/CrudRepositoryInvokerUnitTests.java index 87befbd554..d42a8a7fa5 100755 --- a/src/test/java/org/springframework/data/repository/support/CrudRepositoryInvokerUnitTests.java +++ b/src/test/java/org/springframework/data/repository/support/CrudRepositoryInvokerUnitTests.java @@ -153,7 +153,7 @@ interface OrderRepository extends CrudRepository { static class Person {} - interface PersonRepository extends PagingAndSortingRepository { + interface PersonRepository extends PagingAndSortingRepository, CrudRepository { Page findByFirstName(@Param("firstName") String firstName, Pageable pageable); diff --git a/src/test/java/org/springframework/data/repository/support/DefaultRepositoryInvokerFactoryIntegrationTests.java b/src/test/java/org/springframework/data/repository/support/DefaultRepositoryInvokerFactoryIntegrationTests.java index 95f2474ebb..cabf4631b8 100755 --- a/src/test/java/org/springframework/data/repository/support/DefaultRepositoryInvokerFactoryIntegrationTests.java +++ b/src/test/java/org/springframework/data/repository/support/DefaultRepositoryInvokerFactoryIntegrationTests.java @@ -93,7 +93,6 @@ void createsCrudRepositoryInvokerForRepositoryExtendingCrudRepository() { var invoker = factory.getInvokerFor(User.class); assertThat(invoker)// - .isInstanceOf(CrudRepositoryInvoker.class)// - .isNotInstanceOf(PagingAndSortingRepositoryInvoker.class); + .isInstanceOf(CrudRepositoryInvoker.class); } } diff --git a/src/test/java/org/springframework/data/repository/support/PaginginAndSortingRepositoryInvokerUnitTests.java b/src/test/java/org/springframework/data/repository/support/PaginginAndSortingRepositoryInvokerUnitTests.java deleted file mode 100755 index eb6571f0ca..0000000000 --- a/src/test/java/org/springframework/data/repository/support/PaginginAndSortingRepositoryInvokerUnitTests.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2014-2021 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.repository.support; - -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; -import static org.springframework.data.repository.support.RepositoryInvocationTestUtils.*; - -import org.junit.jupiter.api.Test; - -import org.springframework.core.convert.support.GenericConversionService; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.data.repository.PagingAndSortingRepository; -import org.springframework.data.repository.core.RepositoryMetadata; -import org.springframework.data.repository.core.support.DefaultRepositoryMetadata; -import org.springframework.format.support.DefaultFormattingConversionService; - -/** - * Unit tests for {@link PagingAndSortingRepositoryInvoker}. - * - * @author Oliver Gierke - */ -class PaginginAndSortingRepositoryInvokerUnitTests { - - @Test // DATACMNS-589 - void invokesFindAllWithPageableByDefault() throws Exception { - - var repository = mock(Repository.class); - var method = PagingAndSortingRepository.class.getMethod("findAll", Pageable.class); - - getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(PageRequest.of(0, 10)); - getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(Pageable.unpaged()); - } - - @Test // DATACMNS-589 - void invokesFindAllWithSortByDefault() throws Exception { - - var repository = mock(Repository.class); - var method = PagingAndSortingRepository.class.getMethod("findAll", Sort.class); - - getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(Sort.by("foo")); - getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(Sort.unsorted()); - } - - @Test // DATACMNS-589 - void invokesRedeclaredFindAllWithPageable() throws Exception { - - var repository = mock(RepositoryWithRedeclaredFindAllWithPageable.class); - var method = RepositoryWithRedeclaredFindAllWithPageable.class.getMethod("findAll", Pageable.class); - - when(repository.findAll(any(Pageable.class))).thenReturn(Page.empty()); - - getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(PageRequest.of(0, 10)); - getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(Pageable.unpaged()); - } - - @Test // DATACMNS-589 - void invokesRedeclaredFindAllWithSort() throws Exception { - - var repository = mock(RepositoryWithRedeclaredFindAllWithSort.class); - var method = RepositoryWithRedeclaredFindAllWithSort.class.getMethod("findAll", Sort.class); - - getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(Sort.by("foo")); - getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(Sort.unsorted()); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - private static RepositoryInvoker getInvokerFor(Object repository) { - - RepositoryMetadata metadata = new DefaultRepositoryMetadata(repository.getClass().getInterfaces()[0]); - GenericConversionService conversionService = new DefaultFormattingConversionService(); - - return new PagingAndSortingRepositoryInvoker((PagingAndSortingRepository) repository, metadata, conversionService); - } - - private static RepositoryInvoker getInvokerFor(Object repository, VerifyingMethodInterceptor interceptor) { - return getInvokerFor(getVerifyingRepositoryProxy(repository, interceptor)); - } - - interface Repository extends PagingAndSortingRepository {} - - interface RepositoryWithRedeclaredFindAllWithPageable extends PagingAndSortingRepository { - - Page findAll(Pageable pageable); - } - - interface RepositoryWithRedeclaredFindAllWithSort extends PagingAndSortingRepository { - - Page findAll(Sort sort); - } -}