2010-10-20 4 views
7

У меня есть вопрос, который, я думаю, должен быть довольно распространенным я не могу найти ответ.hibernate @ManyToMany двунаправленный нетерпеливый выбор

У меня есть 2 объекта: группа и пользователь. Мои классы выглядят примерно так:

class Group 
{ 
    @ManyToMany(fetch = FetchType.EAGER) 
    List<User> users; 
} 

class User 
{ 
    @ManyToMany(fetch = FetchType.EAGER) 
    List<Group> groups; 
} 

Теперь, когда я пытаюсь получить пользователь из базы данных она приносит все его группа и все группы объединяют все свои пользователь и так далее. Наконец, я получаю исключение stackoverflow.

Как я могу решить эту проблему и все еще иметь свою двунаправленную связь и возможность доступа к объектам в списках?

ответ

8

Вы получаете ту же самую проблему, если вы сделаете одну из сторон вашего двунаправленного Assocation владеющих стороны объединения с помощью атрибута mappedBy (который вы должны использовать в любом случае)? Как это:

@Entity public class Group { 
    ... 
    @ManyToMany(fetch = FetchType.EAGER, mappedBy="groups") 
    List<User> users; 
} 

@Entity public class User { 
    ... 
    @ManyToMany(fetch = FetchType.EAGER) 
    List<Group> groups; 
} 

Update: Я не могу найти никаких доказательств того, что использование EAGER выборки по обе стороны двунаправленного ассоциации запрещено и AFAIK, нет никакого упоминания о таком ограничении в документации Hibernate и/или спецификации JPA.

На самом деле, в соответствии с this comment от Эммануэль Bernard к какому-то образом (аналогичному) выпуску:

LAZY или EAGER должен быть ортогональным к проблеме бесконечной петли в коде. Hibernate знает, как обрабатывать циклические графы

Для меня выше довольно ясно, Hibernate должен быть в состоянии обрабатывать ваши отображение (как я уже говорил в комментарии), и я был бы соблазн рассматривать любое противоречивое поведение как ошибка.

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

+0

Да. то же самое происходит. я могу понять, что смысл b/c hibernate должен принести все объекты списка для каждого списка, и это бесконечный цикл. мой вопрос в том, можно ли ограничить глубину, в которой спящий режим приводит объекты (что-то вроде fetch_max_depth, но для многих-ко-многим). – refaelos

+0

@ Rafa На самом деле, я ожидал бы, что Hibernate обнаружит цикл и сделает соответствующую вещь (но я не нашел времени, чтобы проверить это). С другой стороны, я не могу сказать, что эта загрузка с нетерпением обе стороны от многих ко многим выглядят как хорошая идея. –

0

Hibernate работает нормально, когда он пытается охотно достать все, что ему нужно. Моделирование объектов должно учитывать спящий режим, поэтому циклы и исключения stackoverflow не будут возникать.

Что я сделал, это удаление одной стороны отношений. Вы можете решить, хотите ли вы удалить эту сторону или оставить ее и определить другую сторону в качестве владельца. Вам также нужно будет удалить желаемую выборку с этой стороны.

Было бы хорошо, если бы спящий режим мог дать механизм определения глубины извлечения во многих отношениях.

0

Возможно, вы захотите установить свойство «hibernate.max_fetch_depth» примерно на 3, чтобы ограничить желаемую выборку.

Смежные вопросы