hibernate @ManyToMany двунаправленный нетерпеливый выбор - PullRequest
7 голосов
/ 20 октября 2010

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

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

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

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

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

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

Ответы [ 3 ]

9 голосов
/ 20 октября 2010

Возникает ли у вас такая же проблема, если вы сделаете одну из сторон двунаправленной ассоциации стороной , владеющей ассоциации, используя атрибут 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;
}

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

На самом деле, согласно этого комментария от Эммануила Бернарда к (как-то похожему) вопросу:

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

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

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

0 голосов
/ 05 января 2011

Возможно, вы захотите установить для свойства "hibernate.max_fetch_depth" что-то вроде 3, чтобы ограничить нетерпеливое получение.

0 голосов
/ 28 октября 2010

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

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

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

...