Что означает владелец отношений в двунаправленных отношениях? - PullRequest
25 голосов
/ 19 января 2012

У меня есть простая модель с объектами Question и Choice.

  • ОДИН вопрос имеет МНОГО ВЫБОРОВ (S).
  • У МНОГО выбора есть ОДИН вопрос

Есть два способа реализовать это с Hibernate

Первая реализация: сторона-владелец - Выбор

Question.java

@OneToMany (mappedBy="question")
private Set choices = new HashSet();

Choice.java

@ManyToOne
@JoinColumn (name="QUESTION_ID")
private Question question;

Реализация вторая: сторона-владелец - вопрос

Question.java

@OneToMany
@JoinColumn (name = "QUESTION_ID")
private Set choices = new HashSet();

Choice.java

@ManyToOne
@JoinColumn (name="QUESTION_ID", updatable = false, insertable = false)
private Question question;

В чем разница между двумя реализациями?

1 Ответ

16 голосов
/ 19 января 2012

Ваш первый пример - нормальное и правильное двунаправленное отображение «один ко многим / многие к одному».Установка Question в Choice -атрибут («сторона-владелец») достаточна для сохранения отношений.Граф сущностей в памяти будет испорчен, пока другая сторона отношения снова не будет считана из базы данных.С точки зрения базы данных владелец - это сущность, которая сохраняется в таблице с столбцом внешнего ключа (то же самое для двунаправленной связи «один к одному»).В спецификации это объясняется следующим образом:

Сторона множества двунаправленных отношений один-ко-многим / многие-к-одному должна быть стороной-хозяином, поэтому элемент mappedBy не может быть указан в ManyToOneаннотация.
....
Двунаправленные отношения между управляемыми объектами будут сохраняться на основе ссылок, хранящихся у стороны-владельца связи.Разработчик несет ответственность за то, чтобы ссылки в памяти, хранящиеся на стороне владельца, и ссылки на обратной стороне соответствовали друг другу при их изменении.В случае однонаправленных отношений «один к одному» и «один ко многим» разработчик обязан обеспечить соблюдение семантики отношений.

В терминах JPA ваш второй примерне имеет собственной стороны из-за отсутствия mappedBy.Вместо этого у вас есть две однонаправленные связи, которые вынуждены использовать тот же столбец, что и хранилище.По крайней мере, в Hibernate 3.5.6 он будет вести себя следующим образом:

  • Установка атрибута Question в choice не сохранит связь.
  • Добавление Choice в question -атрибут не сохранит связь.
  • Чтобы сохранить значение на "QUESTION_ID", оба должны быть установлены (да, также нет - insertable question).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...