Reputation: 351
I'm using the new spring data r2dbc module and i'm able to extract the data using a ReactiveCrudRepository. Now i need to introduce pagination but i cannot manage to do it. I tried with this
public interface TestRepository extends ReactiveCrudRepository<MyEntity, Long> {
Flux<MyEntity> findByEntityId(Long entityId, Pageable page);
}
but when i try to execute this i obtain this error
org.springframework.data.repository.query.ParameterOutOfBoundsException: Invalid parameter index! You seem to have declared too little query method parameters!
at org.springframework.data.repository.query.Parameters.getParameter(Parameters.java:237)
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
is there a way to use pagination with this module?
Upvotes: 13
Views: 17320
Reputation: 12405
The newer versions of Spring Data R2dbc accepts Pageable as @Hantsy mentioned, but there is a catch.
If you are fetching all the records without any WHERE clause then following is NOT working:
public interface MyEntityRepository extends ReactiveCrudRepository<MyEntity, Long> {
Flux<MyEntity> findAll(Pageable pageable);
}
Changing findAll()
to findBy()
is working fine.
public interface MyEntityRepository extends ReactiveCrudRepository<MyEntity, Long> {
Flux<MyEntity> findBy(Pageable pageable);
}
Upvotes: 3
Reputation: 13
I was able to achieve this using spring-boot-starter-data-r2dbc.2.4.3
As @Hantsy said the ReactiveCrudRepository will accept Pageable as a parameter inside of the queries but this won't solve the paging issue. In hibernate you expect to be returned a Page of an Object but for Reactive it's going to be a Flux.
I was however able to achieve this by using the PageImpl class and using the count method from the ReactiveCrudRepository interface.
For example
public interface TestRepository extends ReactiveCrudRepository<MyEntity, Long> {
Flux<MyEntity> findByEntityId(Long entityId, Pageable page);
}
public Mono<<Page<MyEntity>> getMyEntities(Long entityId, PageRequest request) {
return testRepository.findByEntityId(entityId, request)
.collectList()
.zipWith(testRepository.count())
.flatMap(entityTuples ->
new PageImpl<>(entityTuples.getT1(), request, entityTuples.getT2()));
}
Upvotes: 0
Reputation: 9359
The new R2dbcEntityTemplate
Spring Data R2dbc 1.2 contains pagination operations like this.
private final R2dbcEntityTemplate template;
public Flux<Post> findByTitleContains(String name) {
return this.template.select(Post.class)
.matching(Query.query(where("title").like("%" + name + "%")).limit(10).offset(0))
.all();
}
Spring Data R2dbc 1.2 (not released yet) will accept a Pageable
parameter as in Repository
.
public Flux<PostSummary> findByTitleLike(String title, Pageable pageable);
The complete code examples, check here, test codes.
Upvotes: 13
Reputation: 4956
No, there currently is no way to use implicit pagination. You should specify your whole queries to use it.
Here is an example:
@Query("SELECT * FROM my_entity WHERE entity_id = :entityId OFFSET :offset LIMIT :limit")
Flux<MyEntity> findByEntityId(Long entityId, int offset, int limit);
Upvotes: 6