As per the documentation : https://docs.spring.io/spring-data/cassandra/docs/2.1.4.RELEASE/reference/html/#repositories.limit-query-result
Spring cassandra data have made it easy to get the pagination info. But I can't get this to work.
Repo, Call and Errors:
1. Reactive Call
Repo:
public interface MyRepository extends ReactiveCassandraRepository<MyClass, String> {
@Query("select * from my_keyspace.my_table where solr_query = ?0")
Mono<Slice<MyClass>> findMono(String solrQuery, Pageable page);
}
Call:
Mono<Slice<MyClass>> repository.findMono(queryString, CassandraPageRequest.first(20));
Error:
"exceptionDescription":"org.springframework.core.codec.CodecException: Type definition error: [simple type, class com.datastax.driver.core.PagingState]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class com.datastax.driver.core.PagingState and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: org.springframework.data.domain.SliceImpl[\"pageable\"]->org.springframework.data.cassandra.core.query.CassandraPageRequest[\"pagingState\"])","lines":["org.springframework.http.codec.json.AbstractJackson2Encoder.encodeValue(AbstractJackson2Encoder.java:175)","org.springframework.http.codec.json.AbstractJackson2Encoder.lambda$encode$0(AbstractJackson2Encoder.java:122)","reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:100)","reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:67)","reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:114)","reactor.core.publisher.FluxDefaultIfEmpty$DefaultIfEmptySubscriber.onNext(FluxDefaultIfEmpty.java:92)","reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1476)","reactor.core.publisher.MonoFlatMap$FlatMapInner.onNext(MonoFlatMap.java:241)","reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:121)","reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1476)","reactor.core.publisher.MonoCollectList$MonoBufferAllSubscriber.onComplete(MonoCollectList.java:118)","reactor.core.publisher.FluxTake$TakeFuseableSubscriber.onComplete(FluxTake.java:424)","reactor.core.publisher.FluxTake$TakeFuseableSubscriber.onNext(FluxTake.java:404)","reactor.core.publisher.FluxIterable$IterableSubscription.fastPath(FluxIterable.java:311)","reactor.core.publisher.FluxIterable$IterableSubscription.request(FluxIterable.java:198)"],
2. Reactive with ReactiveSortingRepository
Repo:
public interface LocationRepository extends ReactiveSortingRepository<MyClass, String> {
}
Call:
repository.findAll(CassandraPageRequest.first(20))
Error:
Syntax error: findAll can't be applied to CassandraPageRequest.
3. Simple call to get the page.
Repo:
public interface MyRepository extends CassandraRepository<MyClass, MyClassKey> {
Page<MyClass> findByKeyTerminalIdAndSolrQuery(String solrQuery, Pageable page);
}
Error while starting:
Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: Page queries are not supported. Use a Slice query.
4. Using PagingAndSortingRepository
Repo:
public interface MyRepository extends PagingAndSortingRepository<MyClass, MyClassKey> {
}
Call:
Page<Vessel> vessels = repository.findAll(CassandraPageRequest.first(10));
Error:
springframework.data.mapping.PropertyReferenceException: No property findAll found for type MyClass!
Welcome to Stack Overflow.
The first example is the appropriate one:
public interface MyRepository extends ReactiveCassandraRepository<MyClass, String> {
@Query("select * from my_keyspace.my_table where solr_query = ?0")
Mono<Slice<MyClass>> findMono(String solrQuery, Pageable page);
}
Mono<Slice<MyClass>> repository.findMono(queryString, CassandraPageRequest.first(20));
The issue is that Jackson cannot encode a SliceImpl
(implementation of Slice
) as you're passing it to WebFlux (according to the stack trace). So the query yields the right result but you need to pass on the Slice
content, not the Slice
itself if you want to JSON-encode it.
On a related note: ReactiveCassandraRepository
does not implement ReactiveSortingRepository
because Casandra queries with a Sort
argument require always a WHERE
clause. Looking at ReactiveSortingRepository
, you'll see a findAll(Sort)
method that does not take a filter criterion:
public interface ReactiveSortingRepository<T, ID> extends ReactiveCrudRepository<T, ID> {
Flux<T> findAll(Sort sort);
}