Что такое FetchType в JPA/Hibernate?

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

Ответ

FetchType — это перечисление в JPA, определяющее стратегию загрузки связанных сущностей. Оно управляет тем, когда Hibernate загружает данные из базы.

Два типа загрузки:

  1. FetchType.EAGER — связанная сущность загружается немедленно вместе с владельцем.

    • По умолчанию для @ManyToOne и @OneToOne.
    • Риск: Может привести к проблеме N+1 запроса и избыточному потреблению памяти, если загружается много данных.
  2. FetchType.LAZY — связанная сущность загружается только при первом обращении к ней.

    • По умолчанию для @OneToMany и @ManyToMany.
    • Риск: Может вызвать LazyInitializationException, если доступ происходит вне активной сессии Hibernate (например, в слое представления после закрытия транзакции).

Пример использования:

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

    // Покупатель загрузится только при вызове order.getCustomer()
    @ManyToOne(fetch = FetchType.LAZY)
    private Customer customer;

    // Все позиции заказа загрузятся сразу при загрузке Order
    @OneToMany(fetch = FetchType.EAGER, mappedBy = "order")
    private List<OrderItem> items;
}

Рекомендации:

  • Предпочитайте LAZY загрузку по умолчанию для оптимизации производительности.
  • Используйте EAGER осознанно, только когда связанные данные нужны практически всегда.
  • Для решения проблемы N+1 с LAZY используйте JOIN FETCH в JPQL или @EntityGraph.