Как заставить hibernate получать вложенные объекты одним запросом?

Пользователь

от karen.wisozk , в категории: Java , 2 года назад

Как заставить hibernate получать вложенные объекты одним запросом?

Facebook Vk Ok Twitter LinkedIn Telegram Whatsapp

2 ответа

Пользователь

от shirley.vonrueden , 2 года назад

@karen.wisozk 

Hibernate предоставляет несколько способов для получения вложенных объектов одним запросом, чтобы избежать проблемы "ленивой инициализации" (lazy loading) и снизить количество запросов к базе данных. Один из таких способов - использование "жадной загрузки" (eager loading) при определении отношений между сущностями.


Для использования жадной загрузки в Hibernate можно использовать аннотацию @ManyToOne, @OneToMany или @ManyToMany с параметром fetch = FetchType.EAGER. Например:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
@Entity
public class Order {
    ...
    @ManyToOne(fetch = FetchType.EAGER)
    private Customer customer;
    ...
}

@Entity
public class Customer {
    ...
    @OneToMany(fetch = FetchType.EAGER, mappedBy = "customer")
    private List<Order> orders;
    ...
}


В этом примере при загрузке заказа будет также загружен и связанный с ним объект Customer, и наоборот, при загрузке объекта Customer будут также загружены связанные с ним объекты Order.


Если вам нужно получить только определенное подмножество вложенных объектов, вы можете использовать параметр fetch = FetchType.LAZY и явно указать, какие свойства должны быть загружены жадно при помощи метода Hibernate.initialize() или запроса с использованием join fetch.


Например:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
@Entity
public class Customer {
    ...
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "customer")
    private List<Order> orders;
    ...
}

List<Customer> customers = session.createQuery("from Customer c join fetch c.orders where c.id = :id", Customer.class)
                .setParameter("id", customerId)
                .getResultList();
Hibernate.initialize(customers.get(0).getOrders());


Этот пример загружает только тех заказчиков, у которых есть заказы, и загружает эти заказы жадно при помощи запроса join fetch. Затем метод Hibernate.initialize() используется для загрузки заказов только для первого заказчика в списке.

Пользователь

от maymie , 9 месяцев назад

@karen.wisozk 

Таким образом, для заставления Hibernate получать вложенные объекты одним запросом, вы можете использовать жадную загрузку (eager loading) с помощью аннотаций или явно указывать, какие свойства должны быть загружены жадно при помощи метода Hibernate.initialize() или запроса с использованием join fetch. Однако необходимо быть осторожным с использованием жадной загрузки, так как это может привести к избыточному объему данных, особенно при работе с крупными объемами информации.