I want to implement the scroll API from Spring. So that when a user scrolls in the Front End, new data is loaded on every request from the Front end.
I try to limit the results returned by Spring and I am trying various ways.
// Service
fun getOrders(customerId: Long): List<OrderDto> {
val customer = customerRepository.findById(customerId).getOrElse { return emptyList() }
val orders: WindowIterator<Order> = WindowIterator.of<Order> { position ->
orderRepsitory.findAllByCustomerOrderByCreated(
customer,
position as KeysetScrollPosition?,
PageRequest.of(0, 20)
)
}
.startingAt(ScrollPosition.keyset())
val ordersResult: MutableList<Orders> = ArrayList<Orders>()
orders.forEachRemaining { ordersResult.add(it) }
return ordersResult.map {
OrderDto(...)
}
}
// Order Respository
interface OrderRepository : JpaRepository<Order, Long> {
fun findAllByCustomerOrderByCreated(
customer: Customer,
position: KeysetScrollPosition?,
pageable: Pageable,
): Window<Order>
}
This always returns the whole table.
// Order Respository
interface OrderRepository : JpaRepository<Order, Long> {
fun findFirst5ByCustomerOrderByCreated(
customer: Customer,
position: KeysetScrollPosition?,
): Window<Order>
}
// call to repository in service
orderRepsitory.findFirst5ByCustomerOrderByCreated(
customer,
position as KeysetScrollPosition?
)
Same result, it returns the whole table.
// Order Respository
interface OrderRepository : JpaRepository<Order, Long> {
fun findAllByCustomerOrderByCreated(
customer: Customer,
limit: Limit,
): Window<Order>
}
// call to repository in service
orderRepsitory.findAllByCustomerOrderByCreated(
customer,
position as KeysetScrollPosition?,
Limit.of(20)
)
Same result, it returns the whole table.
How to limit the results with Spring Scroll API?
The "problem" is your use of the WindowIterator
. This will keep iterating over successive Window
s (which is the point of an iterator) until there is nothing more to retrieve.
So the problem isn't Spring Data, but rather your use of the WindowIterator
. Just remove it and return the Window
as is, or just use toList
to convert it to a List
.
fun getOrders(customerId: Long): List<OrderDto> {
val customer = customerRepository.findById(customerId).getOrElse { return emptyList() }
val orders = orderRepsitory.findAllByCustomerOrderByCreated(
customer,
position as KeysetScrollPosition?,
PageRequest.of(0, 20)
return orders.toList()
}
}