Как я должен передать невыгруженный, но отсортированный Pageable в репозиторий Spring JPA? - PullRequest
0 голосов
/ 06 ноября 2019

Spring JPA имеет интерфейс Pageable. Я могу передать это методу хранилища. Некоторые из его реализаций, такие как PageRequest, содержат page, size и sort. Однако есть также экземпляр unpaged, который я могу создать с помощью Pageable.unpaged() и который возвращает org.springframework.data.domain.Unpaged, представляющий собой перечисление, реализующее Pageable.

Проблема возникает, когда вы хотите использоватьВозможности сортировки этого объекта с возможностью просмотра страниц, но не хотят подкачки страниц. В этом случае вы должны захотеть, чтобы Pageable.isPaged() возвращал false, однако единственный экземпляр этого, который вы обычно можете создать, это PageRequest (с Pagerequest.of(size, page, sort)), который всегда возвращает true для этого метода.

Если выесть метод репозитория JPA, подобный этому:

Page<EventTriggerVersion> findByProjectIdAndEventTriggerId(
    @Param("projectId") UUID projectId, @Param("eventTriggerId") UUID eventTriggerId, Pageable pageable);

Тогда вы не можете создать для него Pageable, который Сортирует, но НЕ страницы, то есть возвращает только 1 страницу со всеми результатами.

Однако,вы можете ТАКЖЕ не просто присвоить ему и параметр выгружаемой страницы, и параметр сортировки, если вы это сделаете, он выдаст следующее исключение: java.lang.IllegalStateException: Method must not have Pageable *and* Sort parameter. Use sorting capabilities on Pageable instead!

Итак, как я должен это сделать, не дублируя все мои методы репозитория (чтов основном это пользовательские запросы) иметь версию с Pageable и с сортировкой?

Наши пользователи просто хотят передать size=0 в своем запросе и затем получить все данные (не ограничиваясь каким-либо произвольным максимумом, но подлинным невыгруженным запросом)). Это достаточно раздражает, потому что это означает, что мне нужно удалить параметр запроса Pageable из контроллера и вручную создать его из страницы, размера и сортировки, но теперь это даже не представляется возможным без серьезного дублирования кода.

1 Ответ

0 голосов
/ 08 ноября 2019

На данный момент я реализовал свой собственный класс Pageable следующим образом:

import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

public class SortedUnpaged implements Pageable {

    private final Sort sort;

    private SortedUnpaged(Sort sort) {
        this.sort = sort;
    }

    public static SortedUnpaged getInstance(Sort sort) {
        return new SortedUnpaged(sort);
    }

    public boolean isPaged() {
        return false;
    }

    public Pageable previousOrFirst() {
        return this;
    }

    public Pageable next() {
        return this;
    }

    public boolean hasPrevious() {
        return false;
    }

    public Sort getSort() {
        return sort;
    }

    public int getPageSize() {
        throw new UnsupportedOperationException();
    }

    public int getPageNumber() {
        throw new UnsupportedOperationException();
    }

    public long getOffset() {
        throw new UnsupportedOperationException();
    }

    public Pageable first() {
        return this;
    }
}

И у меня в контроллере есть это:

@GetMapping("/{projectId}" + SUBJECTS_PATH)
public ResponseEntity<SubjectWrapperDTO> getSubjects(
    @RequestParam(name = "size", required = false, defaultValue = "20") Integer size,
    @RequestParam(name = "page", required = false, defaultValue = "0") Integer page,
    @SortDefault(sort = "name") Sort sort) {

    Pageable pageable;
    if (size > 0) {
        pageable = PageRequest.of(page, size, sort);
    }
    else {
        pageable = SortedUnpaged.getInstance(sort);
    }
    ...

}

Но это кажется слишком большим для такихосновное требование, и я бы предпочел не реализовывать свои собственные классы интерфейсов Spring.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...