@Loader в Hibernate
Аннотация @Loader позволяет переопределить стандартный SQL-запрос, который Hibernate использует для загрузки сущности из базы данных.
Это полезно для сложных сценариев, когда требуется:
Загружать данные с помощью кастомного SQL (вместо SELECT * FROM table).
Оптимизировать запросы (например, использовать JOIN или подзапросы).
Загружать сущности через хранимые процедуры.
Пакет: org.hibernate.annotations
Применяется к: классу сущности (@Entity).
Параметры и настройки
namedQuery: Именованный запрос (определённый через @NamedQuery).
query: Собственный SQL-запрос (нативный или HQL).
Примеры:
Использование именованного запроса (namedQuery)
Прямое указание SQL (query)
Жизненный цикл и обработка
Когда выполняется кастомный запрос?
При загрузке сущности по ID:
session.get(User.class, 1) → выполняется запрос из @Loader.
При ленивой загрузке прокси:
Если сущность загружается через прокси (например, @ManyToOne с FetchType.LAZY), @Loader не применяется.
Ограничения
Запрос должен возвращать ровно одну сущность.
Параметры:
Для namedQuery — порядковый номер параметра (?1).
Для query — можно использовать ? или именованные параметры (:id).
Механизмы Hibernate и Spring Boot
Интеграция с @NamedQuery:
Если @Loader ссылается на namedQuery, запрос должен быть определён в той же сущности.
Нативные запросы vs HQL:
Если query начинается с SELECT *, Hibernate обрабатывает его как нативный.
Для HQL используйте синтаксис "FROM EntityName WHERE ...".
Влияние кеширования:
@Loader не отключает кеш второго уровня. Если сущность есть в кеше, запрос не выполнится.
Примеры использования
Пример 1: Оптимизированная загрузка с JOIN
Пример 2: Загрузка через хранимую процедуру
Ограничения и лучшие практики
Когда использовать @Loader?
Сложные условия загрузки (например, фильтрация по статусу).
Оптимизация запросов (избегание N+1 через JOIN).
Интеграция с legacy-кодом (хранимые процедуры).
#Java #Training #Hard #Spring #Hibernate #Loader
Аннотация @Loader позволяет переопределить стандартный SQL-запрос, который Hibernate использует для загрузки сущности из базы данных.
Это полезно для сложных сценариев, когда требуется:
Загружать данные с помощью кастомного SQL (вместо SELECT * FROM table).
Оптимизировать запросы (например, использовать JOIN или подзапросы).
Загружать сущности через хранимые процедуры.
Пакет: org.hibernate.annotations
Применяется к: классу сущности (@Entity).
Параметры и настройки
namedQuery: Именованный запрос (определённый через @NamedQuery).
query: Собственный SQL-запрос (нативный или HQL).
Примеры:
Использование именованного запроса (namedQuery)
@Entity
@Loader(namedQuery = "findUserById")
@NamedQuery(name = "findUserById", query = "SELECT u FROM User u WHERE u.id = ?1")
public class User { ... }
Прямое указание SQL (query)
@Entity
@Loader(query = "SELECT * FROM users WHERE user_id = ?1 AND is_active = true")
public class User { ... }
Жизненный цикл и обработка
Когда выполняется кастомный запрос?
При загрузке сущности по ID:
session.get(User.class, 1) → выполняется запрос из @Loader.
При ленивой загрузке прокси:
Если сущность загружается через прокси (например, @ManyToOne с FetchType.LAZY), @Loader не применяется.
Ограничения
Запрос должен возвращать ровно одну сущность.
Параметры:
Для namedQuery — порядковый номер параметра (?1).
Для query — можно использовать ? или именованные параметры (:id).
Механизмы Hibernate и Spring Boot
Интеграция с @NamedQuery:
Если @Loader ссылается на namedQuery, запрос должен быть определён в той же сущности.
Нативные запросы vs HQL:
Если query начинается с SELECT *, Hibernate обрабатывает его как нативный.
Для HQL используйте синтаксис "FROM EntityName WHERE ...".
Влияние кеширования:
@Loader не отключает кеш второго уровня. Если сущность есть в кеше, запрос не выполнится.
Примеры использования
Пример 1: Оптимизированная загрузка с JOIN
@Entity
@Loader(query = """
SELECT u.* FROM users u
LEFT JOIN user_settings s ON u.id = s.user_id
WHERE u.id = ?1
""")
public class User { ... }
Пример 2: Загрузка через хранимую процедуру
@Entity
@Loader(query = "CALL load_user_by_id(:id)")
public class User { ... }
Ограничения и лучшие практики
Когда использовать @Loader?
Сложные условия загрузки (например, фильтрация по статусу).
Оптимизация запросов (избегание N+1 через JOIN).
Интеграция с legacy-кодом (хранимые процедуры).
#Java #Training #Hard #Spring #Hibernate #Loader