Ответ
Основная ошибка – LazyInitializationException, возникающая при попытке доступа к неинициализированной ленивой коллекции вне контекста открытой сессии Hibernate (или EntityManager в JPA).
Типичный сценарий ошибки:
@Entity
public class User {
@Id
private Long id;
@ManyToMany(fetch = FetchType.LAZY) // Загрузка по умолчанию
private Set<Role> roles = new HashSet<>();
}
// В сервисном слое или после закрытия сессии:
User user = entityManager.find(User.class, 1L);
transaction.commit(); // Сессия закрывается
// Попытка доступа к коллекции:
user.getRoles().size(); // LazyInitializationException!
Стратегии решения:
-
Явная инициализация в рамках сессии:
Hibernate.initialize(user.getRoles()); -
Использование JOIN FETCH в JPQL/HQL:
"SELECT u FROM User u JOIN FETCH u.roles WHERE u.id = :id" -
Использование EntityGraph:
@EntityGraph(attributePaths = {"roles"}) User findWithRolesById(Long id); -
Изменение на EAGER (не рекомендуется):
fetch = FetchType.EAGERможет привести к проблемам производительности (N+1 запрос) и неожиданным JOIN в запросах. -
Паттерн Open Session/EntityManager in View (осторожно): Продление контекста persistence до уровня представления. Может создавать проблемы с долгоживущими транзакциями.