Ответ
Разница заключается в стратегии загрузки связанных сущностей.
FetchType.EAGER(жадная): Связанная сущность загружается немедленно, в том же запросе SELECT (или с помощью дополнительного JOIN), что и владеющая сущность.FetchType.LAZY(ленивая): Связанная сущность загружается только при первом явном обращении к этому полю в коде, отдельным запросом.
Настройка:
@Entity
public class Order {
@Id
private Long id;
// EAGER загрузка (по умолчанию для @ManyToOne)
@ManyToOne(fetch = FetchType.EAGER)
private Customer customer;
// LAZY загрузка (по умолчанию для @OneToMany)
@OneToMany(mappedBy = "order", fetch = FetchType.LAZY)
private List<OrderItem> items;
}
Плюсы и минусы:
LAZY:- Плюсы: Повышает производительность начальной загрузки, избегая избыточных JOIN и загрузки ненужных данных.
- Минусы: Может привести к проблеме N+1 SELECT, если лениво загружать коллекции в цикле. Требует открытой сессии/контекста persistence при обращении, иначе выбрасывается
LazyInitializationException.
EAGER:- Плюсы: Данные доступны сразу, нет риска
LazyInitializationException. - Минусы: Может серьезно снижать производительность из-за загрузки больших графов объектов одним запросом (например, загрузка всех заказов со всеми позициями).
- Плюсы: Данные доступны сразу, нет риска
Best Practice: По умолчанию используйте LAZY для всех ассоциаций. Для случаев, когда связанные данные нужны всегда, используйте JOIN FETCH в запросе (JPQL или Criteria API) для эффективной eager-загрузки только когда это необходимо, избегая N+1 проблемы.