Hibernate. Использование именованных запросов (@NamedQueries) на уровне класса

Создадим именованный запрос над классом сущности, который в дальнейшем будет вызываться через специальный метод в репозитории. Именованные запросы, вызываемые через методы репозитерия, рассмотрены в другой статье.

В классе сохраняемой сущности можно объявить один или несколько запросов, дать им имена, а также сопоставить им методы в репозитории, вызывая которые, мы будем запускать эти запросы на выполнение.

Создадим минимальное Spring Boot приложение с поддержкой JPA/Hibernate.

Добавим в проект следующую сущность:

Класс сущности помимо @Entity также помечен аннотацией @NamedQueries. Поскольку это чисто хибернейтовская аннотация, а не стандартная JPA аннотация, то по правилам приличия пишется её полное имя.

В аннотацию @NamedQueries передаётся массив аннотаций @NamedQuery, каждая из которых содержит два поля:

  • name — имя запроса
  • query — собственно код запроса

Причём имя запроса начинается с имени сущности, после которой через точку пишется собственно имя метода, который будет этот запрос запускать (Address.findMoscow).

Далее создадим репозиторий со следующим содержимым:

В репозитории мы создали метод List findMoscow(), название которого дублирует правую часть имени запроса (name = «Address.findMoscow») из аннотации @NamedQuery. Теперь, вызывая этот метод репозитория, мы будем запускать за выполнение соответствующий запрос (query = «select a from Address a where city=’Москва'»).

Создадим тест, который продемонстрирует использование именованного запроса через вызов метода репозитория. Создадим следующий тестовый класс:

Мы создали две сущности типа Address, у одной из которых поле city заполнили строкой «Москва», а у другой, соответственно, — «Санкт-Петербург». Вызвав метод findMoscow() репозитория, мы запустили на выполнение соответствующий запрос, определённый в классе Address. Если имя метода не будет совпадать ни с одним из имён запросов (например, мы где-то опечатаемся), то ошибка выявится на этапе запуска приложения.