В чем разница между:
@Entity
public class Company {
@OneToMany(cascade = CascadeType.ALL , fetch = FetchType.LAZY)
@JoinColumn(name = "companyIdRef", referencedColumnName = "companyId")
private List<Branch> branches;
...
}
а также
@Entity
public class Company {
@OneToMany(cascade = CascadeType.ALL , fetch = FetchType.LAZY, mappedBy = "companyIdRef")
private List<Branch> branches;
...
}
Ответы:
Аннотация
@JoinColumn
указывает, что этот объект является владельцем отношения (то есть: соответствующая таблица имеет столбец с внешним ключом к указанной таблице), тогда как атрибутmappedBy
указывает, что объект на этой стороне является обратным к отношению, и владелец проживает в «другом» юридическом лице. Это также означает, что вы можете получить доступ к другой таблице из класса, который вы аннотировали с помощью "mappedBy" (полностью двунаправленная связь).В частности, для кода в вопросе правильные аннотации будут выглядеть так:
источник
@JoinColumn
вCompany
Branch
нет свойства, которое ссылаетсяCompany
, но в базовой таблице есть столбец, который имеет, то вы можете использовать его@JoinTable
для сопоставления. Это необычная ситуация, потому что вы обычно сопоставляете столбец в объекте, который соответствует его таблице, но это может произойти, и это совершенно законно.@OneToOne
, дочерние строки обновлялисьnull
в столбце FKey, который ссылается на родителя.@JoinColumn
может быть использован по обе стороны отношений. Вопрос был об использовании@JoinColumn
на@OneToMany
стороне (редкий случай). И дело здесь в дублировании физической информации (имени столбца) наряду с неоптимизированным SQL-запросом, который будет производить некоторые дополнительныеUPDATE
операторы .Согласно документации :
Поскольку многие к одному всегда (почти) всегда являются стороной владельца двунаправленных отношений в спецификации JPA, связь один ко многим аннотируется
@OneToMany(mappedBy=...)
Troop
имеет двунаправленное отношение один-ко-многимSoldier
через свойство войск. Вы не должны (не должны) определять какое-либо физическое отображение вmappedBy
стороне.Чтобы отобразить двунаправленную один ко многим, с одной стороны-ко-многим , как собственницы стороны , вы должны удалить
mappedBy
элемент и установить многие к одному ,@JoinColumn
какinsertable
иupdatable
к ложному. Это решение не оптимизировано и будет давать некоторые дополнительныеUPDATE
утверждения.источник
mappedBy="troop"
относятся к какому полю?mappedBy="troop"
относится к отряду свойств в классе Soldier. В приведенном выше коде свойство не видно, потому что здесь Михайло его опускает, но вы можете определить его существование с помощью getTroop (). Проверьте ответ Оскара Лопеса , это очень ясно, и вы получите точку.Однонаправленная ассоциация «один ко многим»
Как я объяснил в этой статье , если вы используете
@OneToMany
аннотацию с@JoinColumn
, то у вас есть однонаправленная связь, такая как связь между родительскойPost
сущностью и дочернейPostComment
на следующей диаграмме:При использовании однонаправленной ассоциации «один ко многим» только родительская сторона отображает ассоциацию.
В этом примере только
Post
сущность будет определять@OneToMany
связь с дочернейPostComment
сущностью:Двунаправленная ассоциация «один ко многим»
Если вы используете
@OneToMany
с установленнымmappedBy
атрибутом, у вас есть двунаправленная связь. В нашем случае иPost
сущность имеет коллекциюPostComment
дочерних сущностей, а дочерняяPostComment
сущность имеет ссылку на родительскуюPost
сущность, как показано на следующей диаграмме:В
PostComment
сущности, тоpost
свойство объекта отображаются следующим образом :В
Post
сущностиcomments
ассоциация отображается следующим образом:mappedBy
Атрибут@OneToMany
ссылки АННОТАЦИИpost
собственности в дочернейPostComment
сущности, и, таким образом, Hibernate знает , что двунаправленная связь контролируется@ManyToOne
стороной, которая отвечает за управление значением столбца внешнего ключа этого отношение таблицы основано на.Для двунаправленной ассоциации, вы также должны иметь два вспомогательных методов, как
addChild
иremoveChild
:Эти два метода гарантируют, что обе стороны двунаправленной ассоциации не синхронизированы. Без синхронизации обоих концов Hibernate не гарантирует, что изменения состояния ассоциации будут распространяться на базу данных.
Какой выбрать?
Однонаправленная
@OneToMany
ассоциация не выполняет очень хорошо , поэтому следует избегать его.Вам лучше использовать двунаправленный,
@OneToMany
который является более эффективным .источник
В идеале аннотацию mappedBy всегда следует использовать в родительской части (класс Company) двунаправленного отношения, в этом случае она должна быть в классе Company, указывая на переменную-член 'company' класса Child (класс Branch)
Аннотация @JoinColumn используется для указания сопоставленного столбца для присоединения к ассоциации сущностей, эту аннотацию можно использовать в любом классе (родительском или дочернем), но в идеале ее следует использовать только на одной стороне (либо в родительском классе, либо в дочернем классе, но не в обоих случаях) здесь, в этом случае, я использовал его в дочерней стороне (класс Branch) двунаправленного отношения, указывающего внешний ключ в классе Branch.
ниже рабочий пример:
родительский класс, компания
детский класс, филиал
источник
Я просто хотел бы добавить, что
@JoinColumn
это не всегда должно быть связано с физическим расположением информации, как предполагает этот ответ. Вы можете комбинировать@JoinColumn
с,@OneToMany
даже если родительская таблица не имеет табличных данных, указывающих на дочернюю таблицу.Как определить однонаправленное отношение OneToMany в JPA
Однонаправленный OneToMany, нет обратного ManyToOne, нет таблицы соединения
Кажется, он доступен только в
JPA 2.x+
. Это полезно в ситуациях, когда вы хотите, чтобы дочерний класс просто содержал идентификатор родителя, а не полную ссылку на него.источник
Я не согласен с принятым здесь ответом Оскара Лопеса. Этот ответ неточный!
Это НЕ
@JoinColumn
означает, что эта сущность является владельцем отношений. Вместо этого это@ManyToOne
аннотация, которая делает это (в его примере).Аннотации отношений, такие как
@ManyToOne
,@OneToMany
и@ManyToMany
говорят JPA / Hibernate для создания отображения. По умолчанию это делается через отдельную таблицу соединений.@JoinColumn
MappedBy
Помните:
MappedBy
это свойство аннотаций отношений, целью которого является создание механизма, связывающего две сущности, что по умолчанию они делают, создавая таблицу соединений.MappedBy
останавливает этот процесс в одном направлении.Считается, что неиспользуемая сущность
MappedBy
является владельцем отношения, поскольку механизм сопоставления определяется в пределах его класса посредством использования одной из трех аннотаций сопоставления для поля внешнего ключа. Это не только определяет характер сопоставления, но и дает указание создать таблицу соединений. Кроме того, опция подавления таблицы соединения также существует путем применения аннотации @JoinColumn к внешнему ключу, которая вместо этого хранит ее в таблице объекта-владельца.Итак, подведем итоги:
@JoinColumn
либо создайте новый столбец соединения, либо переименуйте существующий; в то время какMappedBy
параметр работает совместно с аннотациями отношений другого (дочернего) класса, чтобы создать отображение либо через таблицу соединения, либо путем создания столбца внешнего ключа в связанной таблице объекта-владельца.Чтобы проиллюстрировать, как
MapppedBy
работает, рассмотрим код ниже. ЕслиMappedBy
параметр должен быть удален, то Hibernate фактически создаст ДВЕ таблицы соединения! Почему? Потому что во взаимоотношениях «многие ко многим» существует симметрия, а в Hibernate нет смысла выбирать одно направление над другим.Поэтому мы используем,
MappedBy
чтобы сообщить Hibernate, мы выбрали другую сущность, чтобы диктовать отображение отношений между двумя сущностями.Добавление @JoinColumn (name = "driverID") в класс владельца (см. Ниже) предотвратит создание таблицы соединения и вместо этого создаст столбец внешнего ключа driverID в таблице Cars для построения сопоставления:
источник
JPA является многоуровневым API, различные уровни имеют свои собственные аннотации. Самый высокий уровень - это (1) уровень сущности, который описывает постоянные классы, тогда у вас есть (2) уровень реляционной базы данных, который предполагает, что сущности отображаются в реляционную базу данных и (3) модель Java.
Уровень 1 аннотации:
@Entity
,@Id
,@OneToOne
,@OneToMany
,@ManyToOne
,@ManyToMany
. Вы можете внести постоянство в свое приложение, используя только эти высокоуровневые аннотации. Но тогда вы должны создать свою базу данных в соответствии с предположениями, которые делает JPA. Эти аннотации определяют модель сущности / отношения.Уровень 2 аннотаций:
@Table
,@Column
,@JoinColumn
, ... Влияние на отображение субъектов / свойств для реляционных таблиц базы данных / столбцы , если вы не удовлетворены по умолчанию JPA или , если вам нужно отобразить в существующую базу данных. Эти аннотации можно рассматривать как аннотации реализации, они определяют, как должно выполняться отображение.По моему мнению, лучше всего придерживаться аннотаций высокого уровня, а затем вводить аннотации более низкого уровня по мере необходимости.
Чтобы ответить на вопросы:
@OneToMany
/mappedBy
лучше всего, потому что он использует только аннотации из домена объекта.@oneToMany
/@JoinColumn
Тоже хорошо , но он использует аннотацию реализации , где это не является строго необходимым.источник
Позвольте мне сделать это просто.
Вы можете использовать @JoinColumn с обеих сторон независимо от отображения.
Давайте разделим это на три случая.
1) Однонаправленное отображение от филиала к компании.
2) Двунаправленное картирование от компании к филиалу.
3) Только однонаправленное отображение от компании к филиалу.
Таким образом, любой вариант использования подпадает под эти три категории. Итак, позвольте мне объяснить, как использовать @JoinColumn и mappedBy .
1) Однонаправленное отображение от филиала к компании.
Используйте JoinColumn в таблице Branch.
2) Двунаправленное картирование от компании к филиалу.
Используйте mappedBy в таблице компаний, как описано в ответе @Mykhaylo Adamovych.
3) Однонаправленное отображение от Компании к Филиалу.
Просто используйте @JoinColumn в таблице компании.
Это говорит о том, что, основываясь на отображении внешнего ключа "courseId" в таблице ветвей, получите список всех ветвей. ПРИМЕЧАНИЕ: в этом случае вы не можете получить компанию из филиала, существует только однонаправленное отображение от компании к филиалу.
источник