Выборка и сортировка данных отображаемых коллекций оператором ORDER BY вызываемым аннотацией @javax.persistence.annotations.OrderBy

Если отображаемый класс содержит поле типа коллекции, поддерживающей порядок элементов, например, List<String> emails, то с помощью аннотации @javax.persistence.annotations.OrderBy можно указать Hibernate’у добавлять в конец запроса на выборку выражение ORDER BY COLUMN_NAME ASC. В результате данные в такую коллекцию попадут отсортированными ещё в БД.

Подготовка

Создадим базовое веб-приложения на связке Spring Boot 3 + Hibernate + PostgreSQL

Убедитесь, что файле /src/main/resources/application.properties есть следующая строка, позволяющая Hibernate’у автоматически создавать (и обновлять) схему БД при запуске приложения на основании аннотаций в классах предметной области:

spring.jpa.hibernate.ddl-auto=update

Также добавим в application.properties настройку, позволяющую видеть создаваемый Hibernate’ом SQL в консоли:

spring.jpa.show-sql=true

Код

Создадим класс предметной области, содержащий поле типа List<String>:

Мы помечаем поле List<String> emails аннотацией @javax.persistence.annotations.OrderBy, указывая Hibernate’у добавить в конец запроса на выборку выражение ORDER BY EMAILS ASC.

Создадим репозиторий с кастомным запросом, который будет делать выборку из двух таблиц: PERSON и из связанной с ней таблицы EMAILS:

Напишем тест, который продемонстрирует работу нашего кода:

Мы сохраняем объект irina в БД, добавив в поле List<String> emails строки в порядке обратном алфавитному. Затем мы делаем выборку и показываем, что после выборки из БД строки в списке отсортированы в алфавитном порядке.

Обратим внимание на то, как выглядел запрос на выборку:

select p1_0.id,e1_0.person_id,e1_0.email,p1_0.name
from person p1_0 left join emails e1_0 on p1_0.id=e1_0.person_id
where p1_0.id=?
order by e1_0.email asc

Мы видим, что оператор ORDER BY добавлен в запрос, а значит сортировка данных произошла в БД.

Сравним порядок полученных данных с тем, как они хранятся в БД:

В БД, как и ожидалось, строки сохранились в порядке обратном алфавитному.

Отметим, что использование аннотации @javax.persistence.annotations.OrderBy позволяет только указывать провайдеру персистенции (в нашем случае Hibernate’у) только добавлять выражения восходящей (от меньшего к большему) сортировки типа ORDER BY COLUMN_NAME ASC. Кастомных операторов сортровки таким образом создать нельзя. Для кастомных операторов можно использовать Hibernate’овскую аннотацию @org.hibernate.annotations.OrderBy.