Когда Hibernate загружает поле сущности?

«Когда Hibernate загружает поле сущности?» — вопрос из категории Hibernate, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Момент загрузки поля определяется стратегией выборки (fetch strategy).

Стратегии по умолчанию:

  • FetchType.EAGER (Немедленная): Поле загружается вместе с основной сущностью в одном SELECT.
    • Применяется для: @Basic, @ManyToOne, @OneToOne.
  • FetchType.LAZY (Ленивая): Поле загружается при первом обращении к нему в коде, что может вызвать дополнительный SELECT или LazyInitializationException вне сессии.
    • Применяется для: @OneToMany, @ManyToMany.

Пример с аннотациями:

@Entity
public class Author {
    @Id
    private Long id;

    @Basic // EAGER по умолчанию
    private String name;

    @OneToMany(mappedBy = "author", fetch = FetchType.LAZY) // Явно указана ленивая загрузка
    private List<Book> books;

    @ManyToOne // EAGER по умолчанию
    @JoinColumn(name = "publisher_id")
    private Publisher publisher;
}

Когда происходит загрузка?

  1. Для EAGER: В момент выполнения запроса, загружающего сущность Author.
  2. Для LAZY: В момент первого вызова author.getBooks().

Управление загрузкой в запросе (JPQL/HQL):

Используйте JOIN FETCH, чтобы явно загрузить ленивую связь в одном запросе и избежать N+1 проблемы.

SELECT a FROM Author a JOIN FETCH a.books WHERE a.id = :id

Важно: Стратегию можно переопределять аннотациями (@Fetch) или в запросах. Ленивая загрузка — предпочтительная стратегия по умолчанию для оптимизации.