Decouple Paging and Sorting repositories from CrudRepository.
This way they can be combined with different variants of CrudRepositories. This affects `PagingAndSortingRepository`, `ReactiveSortingRepository`, `CoroutineSortingRepository`, and `RxJavaSortingRepository`. Any repository implementing those interfaces now needs to also implement a suitable CRUD repository, or needs to manually add the methods from a CRUD repository as needed. Closes #2537 Original pull request: #2540.
This commit is contained in:
committed by
Mark Paluch
parent
c9cdc93809
commit
37eee0e35d
@@ -58,13 +58,13 @@ public interface CrudRepository<T, ID> extends Repository<T, ID> {
|
||||
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<T, ID> extends CrudRepository<T, ID> {
|
||||
public interface PagingAndSortingRepository<T, ID> {
|
||||
|
||||
Iterable<T> 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<T>`, `List<T>`, `Collection<T>` 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):
|
||||
|
||||
|
||||
@@ -20,16 +20,19 @@ import org.springframework.data.domain.Pageable;
|
||||
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<T, ID> extends CrudRepository<T, ID> {
|
||||
public interface PagingAndSortingRepository<T, ID> extends Repository<T, ID> {
|
||||
|
||||
/**
|
||||
* Returns all entities sorted by the given options.
|
||||
|
||||
@@ -20,20 +20,24 @@ import reactor.core.publisher.Mono;
|
||||
|
||||
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<T, ID> extends ReactiveCrudRepository<T, ID> {
|
||||
public interface ReactiveSortingRepository<T, ID> extends Repository<T, ID> {
|
||||
|
||||
/**
|
||||
* Returns all entities sorted by the given options.
|
||||
|
||||
@@ -19,18 +19,21 @@ import io.reactivex.rxjava3.core.Flowable;
|
||||
|
||||
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<T, ID> extends RxJava3CrudRepository<T, ID> {
|
||||
public interface RxJava3SortingRepository<T, ID> extends Repository<T, ID> {
|
||||
|
||||
/**
|
||||
* Returns all entities sorted by the given options.
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Christoph Strobl
|
||||
* @author Jens Schauder
|
||||
* @since 1.10
|
||||
*/
|
||||
public class DefaultRepositoryInvokerFactory implements RepositoryInvokerFactory {
|
||||
@@ -93,7 +94,7 @@ public class DefaultRepositoryInvokerFactory implements RepositoryInvokerFactory
|
||||
@SuppressWarnings("unchecked")
|
||||
protected RepositoryInvoker createInvoker(RepositoryInformation information, Object repository) {
|
||||
|
||||
if (repository instanceof PagingAndSortingRepository) {
|
||||
if (repository instanceof PagingAndSortingRepository && repository instanceof CrudRepository) {
|
||||
return new PagingAndSortingRepositoryInvoker((PagingAndSortingRepository<Object, Object>) repository, information,
|
||||
conversionService);
|
||||
} else if (repository instanceof CrudRepository) {
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.Optional;
|
||||
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 @@ import org.springframework.data.repository.core.RepositoryMetadata;
|
||||
* 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<Object, Object> repository,
|
||||
RepositoryMetadata metadata, ConversionService conversionService) {
|
||||
|
||||
super(repository, metadata, conversionService);
|
||||
super((CrudRepository<Object, Object>) repository, metadata, conversionService);
|
||||
|
||||
var crudMethods = metadata.getCrudMethods();
|
||||
|
||||
|
||||
@@ -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<T, ID> : CoroutineCrudRepository<T, ID> {
|
||||
interface CoroutineSortingRepository<T, ID> : Repository<T, ID> {
|
||||
|
||||
/**
|
||||
* Returns all entities sorted by the given options.
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.springframework.core.ResolvableType;
|
||||
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 @@ class AbstractRepositoryMetadataUnitTests {
|
||||
@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 @@ class AbstractRepositoryMetadataUnitTests {
|
||||
interface ContainerRepository extends Repository<Container, Long> {
|
||||
Container someMethod();
|
||||
}
|
||||
|
||||
interface CompletePageableAndSortingRepository extends PagingAndSortingRepository<Container, Long> {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ class DefaultCrudMethodsUnitTests {
|
||||
|
||||
interface DomainCrudRepository extends CrudRepository<Domain, Long> {}
|
||||
|
||||
interface DomainPagingAndSortingRepository extends PagingAndSortingRepository<Domain, Long> {}
|
||||
interface DomainPagingAndSortingRepository extends PagingAndSortingRepository<Domain, Long>, CrudRepository<Domain, Long> {}
|
||||
|
||||
interface RepositoryWithCustomSave extends Repository<Domain, Serializable> {
|
||||
|
||||
|
||||
@@ -111,27 +111,11 @@ class DefaultRepositoryInformationUnitTests {
|
||||
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 @@ class DefaultRepositoryInformationUnitTests {
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
|
||||
interface CompletePageableAndSortingRepository<T, ID> extends CrudRepository<T, ID>, PagingAndSortingRepository<T, ID> {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ class ReactiveRepositoryInformationUnitTests {
|
||||
@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");
|
||||
|
||||
@@ -20,6 +20,7 @@ import static org.mockito.Mockito.*;
|
||||
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<Object, Serializable> backingRepo;
|
||||
@Mock ReactiveCrudRepository<Object, Serializable> backingRepo;
|
||||
@Mock ObjectRepositoryCustom customImplementation;
|
||||
|
||||
@BeforeEach
|
||||
|
||||
@@ -51,6 +51,7 @@ import org.springframework.data.domain.Pageable;
|
||||
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<Object, Object> backingRepo;
|
||||
@Mock CrudRepository<Object, Object> backingRepo;
|
||||
@Mock ObjectRepositoryCustom customImplementation;
|
||||
|
||||
@Mock MyQueryCreationListener listener;
|
||||
@@ -167,12 +168,11 @@ class RepositoryFactorySupportUnitTests {
|
||||
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
|
||||
|
||||
@@ -153,7 +153,7 @@ class CrudRepositoryInvokerUnitTests {
|
||||
|
||||
static class Person {}
|
||||
|
||||
interface PersonRepository extends PagingAndSortingRepository<Person, Long> {
|
||||
interface PersonRepository extends PagingAndSortingRepository<Person, Long>, CrudRepository<Person, Long> {
|
||||
|
||||
Page<Person> findByFirstName(@Param("firstName") String firstName, Pageable pageable);
|
||||
|
||||
|
||||
@@ -93,7 +93,6 @@ class DefaultRepositoryInvokerFactoryIntegrationTests {
|
||||
var invoker = factory.getInvokerFor(User.class);
|
||||
|
||||
assertThat(invoker)//
|
||||
.isInstanceOf(CrudRepositoryInvoker.class)//
|
||||
.isNotInstanceOf(PagingAndSortingRepositoryInvoker.class);
|
||||
.isInstanceOf(CrudRepositoryInvoker.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Object, Long> {}
|
||||
|
||||
interface RepositoryWithRedeclaredFindAllWithPageable extends PagingAndSortingRepository<Object, Long> {
|
||||
|
||||
Page<Object> findAll(Pageable pageable);
|
||||
}
|
||||
|
||||
interface RepositoryWithRedeclaredFindAllWithSort extends PagingAndSortingRepository<Object, Long> {
|
||||
|
||||
Page<Object> findAll(Sort sort);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user