Этот вопрос проверяет понимание механизма ленивой загрузки в Hibernate и типичных ошибок, возникающих при работе с отложенной инициализацией коллекций вне сессии.
LazyInitializationException — это исключение времени выполнения, специфичное для Hibernate (и других реализаций JPA), которое сигнализирует о попытке доступа к данным, которые должны быть загружены "лениво", но контекст persistence (сессия) уже закрыт.
По умолчанию Hibernate загружает сущности и их простые поля сразу, но для коллекций (например, List<Order> у сущности Customer) и ассоциаций "один-ко-многим" применяется ленивая загрузка (FetchType.LAZY). Это означает, что реальные данные коллекции не извлекаются из базы данных до тех пор, пока к ним явно не обратятся в коде. Это оптимизация для избежания N+1 проблемы и лишних JOIN.
// Сервисный метод (сессия открыта здесь)
@Entity
public class Author {
@Id
private Long id;
@OneToMany(mappedBy = "author", fetch = FetchType.LAZY) // Ленивая загрузка по умолчанию
private List<Book> books = new ArrayList<>();
// геттеры и сеттеры
}
// В сервисе
public Author getAuthorWithBooks(Long id) {
EntityManager em = entityManagerFactory.createEntityManager();
Author author = em.find(Author.class, id); // Коллекция books не загружена!
em.close(); // Сессия закрыта
return author;
}
// В другом месте (например, контроллере)
Author author = authorService.getAuthorWithBooks(1L);
for (Book book : author.getBooks()) { // LazyInitializationException здесь!
System.out.println(book.getTitle());
}Hibernate.initialize(collection) или выполните обращение к коллекции (например, вызовите size()) перед закрытием сессии.JOIN FETCH для загрузки коллекции.fetch = FetchType.EAGER в аннотации, но это может привести к проблемам производительности.Вывод: LazyInitializationException — это защитный механизм Hibernate, который указывает на нарушение границ сессии. Для её избежания необходимо явно управлять загрузкой связанных данных в пределах открытой сессии или использовать альтернативные стратегии представления данных, такие как DTO.