Пружинный загрузчик пропускает и дублирует элементы в разбивке по страницам

#java #spring #spring-boot

Вопрос:

У меня есть конечная точка пользователей, чтобы отсортировать всех пользователей в MySQL по логическому значению с помощью разбиения на страницы, поскольку число продолжает расти, я обнаружил, что некоторые пользователи пропускаются и дублируют других. Вот несколько скриншотов в postman, где пользователь с тем же идентификатором (95) дублируется на 2 разных страницах

Также иногда я не могу найти некоторых пользователей на всех страницах

Страница 2

Текст

Страница 3

Текст

Сервисимпл

 @Override
    public PagedResponse<?> findAll(UserPrincipal currentUser, int page, int size) {
        AppUtils.validatePageNumberAndSize(page, size);
//return users with 'isBoard' true first
        Pageable pageable = PageRequest.of(page, size, Sort.Direction.DESC, "isBoard");
        if (currentUser.getAuthorities().contains(new SimpleGrantedAuthority(RoleName.ROLE_ADMIN.toString()))
                || currentUser.getAuthorities().contains(new SimpleGrantedAuthority(RoleName.ROLE_SUPER_ADMIN.toString()))) {
            Page<MEUser> contentPage = userRepository.findAll(pageable);
            List<MEUser> list = contentPage.getNumberOfElements() == 0 ? Collections.emptyList() : contentPage.getContent();
            return new PagedResponse<>(list.stream()
                    .map(user -> mapToAllUsersDTO(user, new AllUserDTO()))
                    .collect(Collectors.toList()), contentPage.getNumber(), contentPage.getSize(), contentPage.getTotalElements(), contentPage.getTotalPages(), contentPage.isLast());
        } else {
            Page<MEUser> contentPage = userRepository.findByMemberTrue(pageable);
            List<MEUser> list = contentPage.getNumberOfElements() == 0 ? Collections.emptyList() : contentPage.getContent();
            return new PagedResponse<>(list.stream()
                    .map(user -> mapToAllUsersDTO(user, new AllUserDTO()))
                    .collect(Collectors.toList()), contentPage.getNumber(), contentPage.getSize(), contentPage.getTotalElements(), contentPage.getTotalPages(), contentPage.isLast());
        }
    }
 

Комментарии:

1. Вы пробовали добавить второй столбец сортировки, чтобы гарантировать согласованный порядок? Попробуйте использовать столбец «если».

Ответ №1:

Это проблема с базой данных, а не в вашем коде. База данных не обеспечивает согласованность результатов, когда имеется несколько строк с одинаковым значением упорядоченного поля.

При использовании разбиения на страницы с LIMIT и OFFSET вы должны указать поле «Заказ по» с уникальными значениями, поэтому в вашем случае вам нужно выполнить сортировку по isBoard и id обеспечить согласованный результат.

Ответ №2:

Это связано с тем, что условие if проверяет только АДМИНИСТРАТОРА и СУПЕРПОЛЬЗОВАТЕЛЯ. у пользователя 95 могут быть другие роли, которые входят в другие условия. Пожалуйста, проверьте один раз и предоставьте информацию о базе данных для ролей и Пользователей.

Комментарии:

1. проблема возникает с ролью администратора

Ответ №3:

я добавил условие идентификатора в разбивку по страницам:

 Pageable pageable = 
  PageRequest.of(page, size, Sort.by("isBoard").descending().and(Sort.by("id")));