Правильный способ запроса объекта с вложенными коллекциями?

Похоже, что базовые запросы не работают, когда элементы коллекции имеют собственные коллекции.

Представьте себе модель данных для банка с клиентами, у которых есть портфели, у которых есть инвестиции. Как правильно привлечь клиентов?

Я пробовал это:

@Query("SELECT DISTINCT c FROM Customer c LEFT JOIN FETCH c.portfolios")

Но это не удается с «Не удалось лениво инициализировать набор ролей».

Инвестиции определяются как:

@ManyToMany(cascade = CascadeType.ALL)

Запрос будет работать, если я изменю fecthType:

@ManyToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER)

Но есть ли способ заставить его работать без изменения типа выборки?

РЕДАКТИРОВАТЬ:

Я должен упомянуть, что я использовал Spring JpaRepository для определения вышеуказанного запроса. У всех сущностей есть соответствующие репозитории, но похоже, что извлечение клиентов не затрагивает какие-либо методы в репозитории портфелей (которые оставили бы СОЕДИНЕНИЕ с инвестициями), поэтому инвестиции никогда не извлекаются.

Кроме того, я могу получить портфель с помощью аналогичного запроса, и он отлично работает, поскольку у инвестиций нет коллекций. Но получить цепочку клиентов -> портфели -> инвестиции не удается.


person wannabeartist    schedule 08.04.2013    source источник
comment
Это должно вам помочь: stackoverflow.com/questions/5404599/   -  person DessDess    schedule 08.04.2013
comment
Я до сих пор не понимаю, почему это работает для сущностей с коллекциями, но не для сущностей с коллекциями, у которых есть коллекции...   -  person wannabeartist    schedule 08.04.2013
comment
Просто вопрос, с отображением ManyToOne вы все еще получаете ошибку?   -  person DessDess    schedule 08.04.2013
comment
У меня есть еще один случай с @OneToMany, и он точно так же не работает. Общим знаменателем является то, что элементы коллекции также имеют коллекции.   -  person wannabeartist    schedule 08.04.2013
comment
Не могли бы вы попробовать без DISTINCT ?   -  person DessDess    schedule 08.04.2013
comment
Пробовал, разницы нет. Я добавил дополнительную информацию в исходный вопрос.   -  person wannabeartist    schedule 08.04.2013


Ответы (1)


Ваш запрос выбирает клиентов и извлекает их портфолио, используя left join fetch. Если вы хотите также получить инвестиции из портфелей, вам потребуется дополнительная выборка соединения, как в SQL:

select distinct c FROM Customer c 
left join fetch c.portfolios portfolio
left join fetch portfolio.investments
person JB Nizet    schedule 08.04.2013
comment
У вас есть какие-либо идеи о том, почему он выдает исключение? Я бы понял, почему он получает это исключение, если он пытается получить доступ к инвестициям, поскольку они не инициализированы, но здесь он не пытается получить инвестиции, так почему это не удается? Я могу быть совершенно не прав... - person DessDess; 08.04.2013
comment
Спасибо, это работает. Но что, если они мне не нужны? Как мне сказать hibernate/jpa игнорировать инвестиции и получать только клиентов и портфели? - person wannabeartist; 08.04.2013
comment
Если вы получаете это исключение, это означает, что вы обращаетесь к коллекции инвестиций. Если они вам не нужны, выполните запрос в своем вопросе без left join fetch portfolio.investments. Исключение, которое вы получаете, точно показывает, что инвестиции не были загружены. - person JB Nizet; 08.04.2013
comment
Если вы получаете это исключение, это означает, что вы обращаетесь к коллекции инвестиций — мне было интересно, где это могло произойти, а потом я понял, что он был преобразован в JSON (все это часть REST API). Это должен быть конвертер JSON, который получает доступ к инвестициям! - person wannabeartist; 08.04.2013