Назад к вопросам

Ответ от нейросети

sobes.tech AI

Fetch type в JPA определяет, как связанные сущности будут загружаться из базы данных. Существует два основных типа: EAGER и LAZY.

  • EAGER: Связанная сущность загружается вместе с основной сущностью при первом же запросе. Это удобно, когда связанная сущность почти всегда нужна, но может привести к избыточной загрузке данных и ухудшению производительности при большом числе связей.

    // Пример EAGER загрузки
    @ManyToOne(fetch = FetchType.EAGER)
    private Address address; // Address будет загружен вместе с User
    
  • LAZY: Связанная сущность загружается только при первом обращении к ней (например, вызове геттера). Это позволяет избежать загрузки ненужных данных, но требует дополнительного запроса к базе при каждом обращении к связанной сущности, что может привести к проблеме "N+1 select".

    // Пример LAZY загрузки
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
    private List<Order> orders; // Orders будет загружен только при вызове user.getOrders()
    

Выбор fetch type — это компромисс между производительностью и удобством. Для большинства коллекций ( @OneToMany, @ManyToMany ) по умолчанию используется LAZY, а для единичных связей ( @ManyToOne, @OneToOne ) — EAGER, за исключением случаев, когда нет аннотации @JoinColumn на владеющей стороне @OneToOne, тогда по умолчанию тоже LAZY. Рекомендуется использовать LAZY по умолчанию и переключаться на EAGER только тогда, когда это оправдано требованиями.

Для оптимизации загрузки при использовании LAZY можно применять JPQL/Criteria запросы с FETCH JOIN или @NamedEntityGraph.