Следует ли избегать двунаправленных ассоциаций Hibernate? - PullRequest
7 голосов
/ 11 сентября 2011

В проекте, основанном на Spring / Hibernate, мы имеем отношение один ко многим между двумя сущностями. Обязательные операции:

  • найти родителя ребенка;
  • найти детей родителей;
  • когда родитель удаляется, нам также нужно удалить детей;
  • массово создай детей.

Мы придумали два способа реализации этого.

  1. Двунаправленная ассоциация : дочерняя сущность имеет столбец @ManyToOne, связывающий ее с родителем, а родительская имеет @OneToMany загруженную ленивыми коллекцию дочерних элементов . Все вышеперечисленные операции можно выполнить в модели:

    child.getParent();
    parent.getChildren(); //lazy loading
    session.delete(parent); //cascade removal of the children does the trick here
    session.save(parent); //cascade persist created the children
    
  2. Однонаправленная ассоциация: дочерний объект имеет столбец @ManyToOne, связывающий его с родителем, но родитель не имеет никакой связи с дочерними элементами . Большинство операций должны выполняться в сервисных методах:

    child.getParent(); //still in the model
    Collection<Child> findChildren(Parent parent); //service method in ChildService
    void deleteChildren(Parent parent); //service method in ChildService
    void createChild(Parent parent, ... childAttributes); //service method in ChildService invoked for each new child.
    

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

Каким должен быть лучший дизайн? Есть ли известные проблемы, производительность или дизайн, созданные двунаправленным подходом?

Ответы [ 4 ]

3 голосов
/ 11 сентября 2011

Если ваши запросы делают то же самое, что и запросы, выполняемые за сценой Hibernate, когда он лениво загружает дочерние элементы, я не вижу, что вы получите, просто не используя ассоциацию OneToMany.

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

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

1 голос
/ 12 сентября 2011

Ответ @JB Низет говорит, что это почти все, только еще одна вещь: если посмотреть на примеры вызовов методов, которые вы разместили, двунаправленный метод, вероятно, сделает ваш код бизнес-логики несколько более читабельным.

0 голосов
/ 20 июня 2016

Да, этого следует избегать, насколько это возможно.если вы действительно думаете, что это ваше требование, то используйте только двунаправленный.например.Emp и Dept, у каждого emp есть один отдел, но в отделе много сотрудников.emp должен знать о своем отделе, но не обязательно, чтобы отдел также знал их отдел.

0 голосов
/ 12 сентября 2011

Пока вы находитесь в ситуации, когда ленивая загрузка действительно работает для вас, я не видел реальной проблемы с двунаправленными отношениями.Однажды я работал над приложением Flex, в котором использовался Hibernate, и двунаправленные связи часто приводили к загрузке всей базы данных при сериализации данных для клиента.

YMMV

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