Hibernate: переопределение EAGER карт в HQL? - PullRequest
18 голосов
/ 18 июня 2010

Возможно переопределить LAZY в HQL, используя LEFT JOIN FETCH.

FROM Obj AS obj LEFT JOIN FETCH obj.otherObj WHERE obj.id = :id

Возможно ли переопределить EAGER? Как?

Ответы [ 2 ]

6 голосов
/ 25 апреля 2013

У меня была ситуация, когда по историческим причинам я не мог выбрать между несколькими зависимостями «один ко многим». С годами многие места стали зависеть от этого, поэтому было трудно отключиться. Тем не менее, в некоторых случаях страстная выборка мешала: для каждого большего выбора в таблице он порождал сотни маленьких подзапросов для каждой из коллекций каждого из объектов. Я нашел способ обойти это, на самом деле не переопределяя нетерпеливую выборку, но для меня так же полезно: просто создать один запрос, который выполняет все подвыборки одновременно. Это сделает 1 физический запрос к базе данных, вместо того, чтобы переходить в спящий режим по графику зависимостей и вызывать сотни запросов.

Так я заменил

Query q = session.createQuery("from Customer c");

от

Query q = session.createQuery("from Customer c " +
                              "left join fetch c.vats v " +
                              "left join fetch v.klMemos bk " +
                              "left join fetch bk.ferryKlMemos");

1 У клиента много номеров НДС, у одного номера НДС много klmemos и так далее. В старой ситуации сначала выбирались только клиенты, а hibernate начинал извлекать каждую из зависимых коллекций одну за другой. Вторая форма загрузит все в одном собственном запросе, и hibernate найдет все, что нужно для заполнения активных коллекций в кеше объектов.

Обратите внимание, что этот подход также имитирует быструю выборку для коллекций, которые настроены как ленивые, поскольку вы заполняете все "ленивые" коллекции энергичным (и эффективным) способом.

4 голосов
/ 19 июня 2010

Спецификатор в этом фрагменте из Hibernate Docs подразумевает, что вы можете переопределить lazy с eager, но не наоборот:

Если вы используете уровень свойствотложенная выборка (с помощью инструментов байт-кода), можно заставить Hibernate немедленно извлечь отложенные свойства в первом запросе, используя выборку всех свойств.

Необычно, если вы используете Критерии, это выглядит как вы.API перейти от нетерпеливых к ленивым.Просто позвоните setFetchMode(FetchMode.LAZY) в соответствующем соединении.

...