Fetch.Lazy при получении списка и Fetch.Eager при возврате одного объекта - PullRequest
1 голос
/ 18 апреля 2020

Я всегда думал, что может быть лучшим способом решения этой проблемы в Spring / Hibernate. Представьте, что у нас есть сущность, подобная Хаусу:

public class House {
    Long id;
    String name;
    String address;
    List<Person> people;
}

Где Person - другая сущность. Теперь, если мы хотим показать список каждого дома, который хранится, мы просто хотим, чтобы некоторые детали, идентификатор, имя и адрес, мы не хотим, чтобы были получены все данные, потому что мы не показываем людей в списке. Однако, когда мы входим в подробный вид, нам также интересно показывать людей.

Каков наилучший способ вызывать людей именно тогда, когда вы их хотите, также заботясь об исключении LazyInitializationException?

Ответы [ 2 ]

2 голосов
/ 18 апреля 2020

Есть множество вариантов. Я просто выделю тот, который я использую:

FETCH JOIN

Если вам нужны загруженные люди, вы можете создать запрос, например:

select h from House h fetch join people p

Если вы думаете, что это приведет ко многим запросам go для графов сущностей.

ENTITY GRAPH

Определение:

@Entity
@NamedEntityGraph(name = "graph.House.people", 
      attributeNodes = @NamedAttributeNode("people"))
public class House {

Использование с Spring Data JPA:

@EntityGraph(value = "graph.House.people", type = EntityGraphType.LOAD)
List<House> findById(Long id);

Но есть и другие. Пожалуйста, прочитайте: https://thoughts-on-java.org/5-ways-to-initialize-lazy-relations-and-when-to-use-them/

1 голос
/ 18 апреля 2020

Вы можете использовать граф сущностей в хранилище. Просто используйте @EntityGraph для определения графа сущностей ad-ho c в вашем методе.

@EntityGraph(attributePaths = {"people"})
List<House> findAll();

Здесь вы можете определить атрибуты, которые вы хотите получить как attributePaths. Вызывайте это, когда хотите показать людям, что в противном случае звоните findAll().

И вы можете использовать ленивую выборку для people также, когда вы хотите people, просто вызовите ее получатель, тогда JPA автоматически получит people в другом запросе.

...