Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a findAll that takes a Pageable and returns a Slice instead of a Page #558

Open
simasch opened this issue Jan 26, 2023 · 6 comments
Open

Comments

@simasch
Copy link

simasch commented Jan 26, 2023

The PagingAndSortingRepository has a Page<T> findAll(Pageable pageable) method.

The problem is that returning a Page will result in a count and a select statement.

The same problem is present in JpaSpecificationExecutor. So it would be awesome to have this covered as well.

@simasch simasch changed the title Add a findAll that takes a Pageable returns a Slice instead of a Page Add a findAll that takes a Pageable and returns a Slice instead of a Page Jan 26, 2023
@vladmihalcea
Copy link
Owner

So, should we define findAll that returns a Slice instead?

One option would be to avoid extending any base interface and create additional interfaces that provide this extra functionality:

  • PagingBaseJpaRepository
  • SlicingBaseJpaRepository

@simasch
Copy link
Author

simasch commented Jan 26, 2023

+1 for the additional interfaces

@josergdev
Copy link

josergdev commented Sep 4, 2024

@vladmihalcea @simasch Can't this be achieved using JpaSpecificationExecutor::findBy method?

<S extends T, R> R findBy(Specification<T> spec, Function<FluentQuery.FetchableFluentQuery<S>, R> queryFunction);

I created this gist: https://gist.github.com/josergdev/06c82891a719eca4834410339885ad23

package dev.joserg.jpa;

import static org.springframework.data.domain.ScrollPosition.offset;

import java.util.function.Function;

import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.ScrollPosition;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.SliceImpl;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Window;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery;

public interface SliceSpecificationExecutor<T> extends JpaSpecificationExecutor<T> {

  default Window<T> findAllWindowed(Specification<T> spec, Sort sort, int limit, ScrollPosition scrollPosition) {
    return this.findBy(spec, toWindow(sort, limit, scrollPosition));
  }

  default Window<T> findAllWindowed(Specification<T> spec, Sort sort, ScrollPosition scrollPosition) {
    return this.findBy(spec, toWindow(sort, scrollPosition));
  }

  default Window<T> findAllWindowed(Specification<T> spec, ScrollPosition scrollPosition) {
    return this.findAllWindowed(spec, Sort.unsorted(), scrollPosition);
  }

  default Slice<T> findAllSliced(Specification<T> spec, Pageable pageable) {
    final var window = pageable.isUnpaged()
        ? this.findAllWindowed(spec, pageable.getSort(), offset())
        : this.findAllWindowed(spec, pageable.getSort(), pageable.getPageSize(), offset(pageable.getOffset()));
    return new SliceImpl<>(window.getContent(), pageable, window.hasNext());
  }

  private static <T> Function<FetchableFluentQuery<T>, Window<T>> toWindow(Sort sort, int limit, ScrollPosition scrollPosition) {
    return fetchableFluentQuery -> fetchableFluentQuery.sortBy(sort).limit(limit).scroll(scrollPosition);
  }

  private static <T> Function<FetchableFluentQuery<T>, Window<T>> toWindow(Sort sort, ScrollPosition scrollPosition) {
    return fetchableFluentQuery -> fetchableFluentQuery.sortBy(sort).scroll(scrollPosition);
  }

}

@vladmihalcea
Copy link
Owner

@josergdev Thanks for the tip.

@abuzar-aftab
Copy link

Is this done?

@vladmihalcea
Copy link
Owner

@abuzar-aftab Be the change you want to see in this world and provide a Pull Request with the fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants