Почему в документах Hibernate рекомендуется использовать таблицу соединений для отношения один ко многим? - PullRequest
9 голосов
/ 12 июля 2011

Я думал, что обычный способ моделирования отношения «один ко многим» в базе данных - через отношение внешнего ключа (т. Е. Один клиент со многими заказами -> таблица заказов получает ссылку FK на таблицу клиентов).

Однако Hibernate рекомендует использовать таблицу соединений для моделирования таких отношений:

Однонаправленный метод «один ко многим», использующий столбец внешнего ключа в принадлежащем объекте, не столь распространен и не рекомендуется.Мы настоятельно рекомендуем вам использовать таблицу соединений для такого рода связей (как описано в следующем разделе).Этот тип ассоциации описывается через @ JoinColumn.

http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html/entity.html#entity-mapping-association

Почему это «не рекомендуется».Я думал, что использование FK было стандартом, и что таблицы соединений используются только для отношений «многие ко многим»?

Мне не нравится создавать таблицу соединений, потому что модель данных будет выглядеть какотношение «многие ко многим», хотя на самом деле это отношение «один ко многим».

В чем причина этой рекомендации в документах Hibernate?

Ответы [ 4 ]

5 голосов
/ 22 июля 2011

Этот вопрос задавался и отвечался на форумах Hibernate: https://forum.hibernate.org/viewtopic.php?t=954178&highlight=unidirectional+null+foriegn+foreign+key. Похоже, это не проблема дизайна БД, а скорее вопрос о том, как функционирует Hibernate.

3 голосов
/ 12 июля 2011

Цитата из имеющейся у вас документации описывает однонаправленную @OneToMany ассоциацию, что является другой вещью. В такой ассоциации у вас есть только ссылка Клиента на Заказы, а не наоборот. Таким образом, сопоставление такого рода ассоциации должно быть выполнено с помощью объединяющей таблицы, содержащей набор заказов для каждого клиента.

Я полагаю, что ассоциация, о которой вы думаете, скорее всего, является ассоциацией @ManyToOne, имеющей ссылку из Заказа на Заказчика.

Обратите внимание, что если вы хотите смоделировать двунаправленную связь, вы можете использовать атрибут "mappedBy" в аннотации @OneToMany.

2 голосов
/ 24 июля 2011

Предыдущий раздел в документах Hibernate охватывает двунаправленные отношения «один ко многим» и описывает то, к чему вы, вероятно, привыкли, со стандартным внешним ключом для множества сущностей. Как уже говорили другие, этот ответ подходит только тогда, когда вы явно хотите однонаправленные отношения.

Вы бы хотели однонаправленности, только если многие стороны не должны знать об отношениях. Это означает, что класс со стороны не может иметь атрибут для представления отношений, почти по определению. Поэтому подумайте об этой проблеме как о вопросе «как мне представить отношения один-ко-многим без обычного подхода».

Желание однонаправленных отношений, таких как это, конечно, несколько необычно, но я могу видеть ситуации, когда вы могли бы хотеть их по причинам разъединения, безопасности, аудита или неизменности. Например, предположим, что вы моделируете клиническое испытание, и ваши занятия проводятся по типу «Пациент и лекарства», и во время испытания вы предоставляете каждому пациенту один из наборов лекарств. Вы хотите, чтобы любая логика, действующая на пациента, была полностью отделена от того, какое лекарство им выделено. Таким образом, вместо использования Patient.setMedication (), как обычно, вы создаете класс соединения MedicationPatientMap и вызываете medication.getMedicationPatientMap (). AddPatient (Patient). Затем вы можете контролировать доступ к лекарству для пациента один-ко-многим с логикой на стороне лекарства.

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

2 голосов
/ 22 июля 2011

Я не могу говорить с какими-либо полномочиями, но я всегда исходил из того, что при однонаправленных отношениях существует более высокая вероятность того, что ваш Орден будет на приемном конце множества таких отношений. Это также увеличивает вероятность того, что Орден будет иметь нулевые значения в некоторых из этих столбцов, потому что Орден был создан, но другие объекты, которые могут ссылаться на Орден, либо еще не существуют, либо никогда не будут. В этом смысле вопрос нормализации - перенести столбцы FK в другую таблицу. Тогда есть еще и тот факт, что он лучше отражает отношения объекта. В однонаправленном режиме «один-к-одному» из Foo -> Bar вы ожидаете найти FK в Foo, а не в Bar, потому что именно там находится владелец объектной модели. То же самое относится и к uni-one-to-many из Customer -> Order. Глядя на объектную модель, вы не ожидаете увидеть право собственности, представленное в Ордене, а значит, и в таблице Ордера.

...