In my Java project, using SeedStack, I have queries to retrive data from an aggregate using specifications like this:
UPDATE: Code example fixed to show the correct return type method
public interface ProductRepository extends Repository<Product, ProductId> {
default Stream<Product> discontinuedProducts() {
return get(getSpecificationBuilder().of(Product.class)
.property("discontinued").equalTo(true)
.build()
);
}
}
In order to avoid potential out-of-memory errors, I want to use pagination to split data retrieved in some repository queries.
Moreover, I would like to use something very similar to pagination feature existing in String Data Repositories. I would like to keep some elements of the result (and not all of them) and process them by "page" without keeping all the data result in a Collection.
Paging and Sorting in Spring: https://docs.spring.io/spring-data/rest/docs/2.0.0.M1/reference/html/paging-chapter.html
However, I read SeedStack documentation and I did not find this feature.
Repositories in SeedStack: http://seedstack.org/docs/business/repositories/
So, I want to know what is the best way to paginate query results using SeedStack.
SeedStack provides helpers to do pagination in several differents ways but sadly the documentation is lacking on this front.
Before we go into details please note that you discontinuedProducts()
method should return a Stream<Product>
and not a List<Product>
because the get
method of the repository returns a stream.
The main way to do pagination with SeedStack is to use the Paginator DSL which plugs on top of a repository to provide the pagination.
Example 1 (paginating the stream directly):
public class SomeResource {
@Inject
private Paginator paginator;
@Inject
private ProductRepository productRepository;
@Inject
private FluentAssembler fluentAssembler;
public void someMethod() {
Page<Product> page = paginator.paginate(productRepository.discontinuedProducts())
.byPage(1)
.ofSize(10)
.all();
}
}
Example 2 (paginating the repository with a spec):
public class SomeResource {
@Inject
private Paginator paginator;
@Inject
private ProductRepository productRepository;
@Inject
private SpecificationBuilder specificationBuilder;
public void someMethod() {
Page<Product> page = paginator.paginate(productRepository)
.byPage(1)
.ofSize(10)
.matching(specificationBuilder.of(Product.class)
.property("discontinued").equalTo(true)
.build());
}
}
Example 3 (adding the DTO mapping in the mix):
public class SomeResource {
@Inject
private Paginator paginator;
@Inject
private ProductRepository productRepository;
@Inject
private SpecificationBuilder specificationBuilder;
@Inject
private FluentAssembler fluentAssembler;
public void someMethod() {
Page<ProductDto> page = fluentAssembler.assemble(
paginator.paginate(productRepository)
.byPage(1)
.ofSize(10)
.matching(specificationBuilder.of(Product.class)
.property("discontinued").equalTo(true)
.build()))
.toPageOf(ProductDto.class)
}
}
In this last example, SeedStack will:
Note that if you are going to reuse the same specification over and over, it may be useful to turn it into a class (like
DiscontinuedProductSpec
) or create a method in your repository to build it (likebuildDiscontinuedProductSpec()
).
There are several other ways to combine these tools, please check the Javadoc of the Paginator , FluentAssembler and Repository . You can also have a look at the pagination integration test for more examples.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.