В JPA есть атрибут referencedColumnName
, который может быть установлен на @JoinColumn, @PrimaryKeyJoinColumn
, в чем заключается идея этой настройки, может ли кто-нибудь дать хороший пример того, где это можно использовать?
Что называется ссылочным именем ColumnName, используемым в JPA?
Ответ 1
Здесь указывается другой столбец как столбец id по умолчанию другой таблицы, например. рассмотрим следующее
TableA
id int identity
tableb_key varchar
TableB
id int identity
key varchar unique
// in class for TableA
@JoinColumn(column="tableb_key", referencedColumnName="key")
Ответ 2
"referencedColumnName" свойство - это имя столбца таблицы, в котором вы ссылаетесь на колонку, которую вы анотируете. Или кратко: это столбец, на который ссылается таблица назначения. Представьте себе что-то вроде этого: машины и люди. У одного человека может быть много автомобилей, но один автомобиль принадлежит только одному человеку (извините, я не люблю, чтобы кто-то еще водил мою машину).
Таблица Person
имя char (64) первичный ключ
возраст intНастольный автомобиль
car_registration char (32) первичный ключ
car_brand (char 64)
car_model (char64)
owner_name char (64) ссылки на внешние ключи Лицо (имя)
Когда вы реализуете классы, у вас будет что-то вроде
class Person{
...
}
class Car{
...
@ManyToOne
@JoinColumn(columnName="owner_name", referencedColumnName="name")
private Person owner;
}
Надеюсь, что это поможет.
Ответ 3
Цитата API для ссылочного имени столбца:
Имя столбца, на которое ссылается этот внешний ключ столбец.
По умолчанию (применяется только при использовании столбца с одним соединением): То же имя, что и столбец первичного ключа в ссылочной таблице.
Q/
Где это будет использоваться?
Когда в ссылочной таблице имеется составная таблица PK, вам нужно указать имя столбца, на которое вы ссылаетесь.
Ответ 4
-
name
атрибут указывает на столбец, содержащий асоциацию, то есть имя столбца внешнего ключа Атрибут -
referencedColumnName
указывает на соответствующий столбец в объекте asociated/referenced, то есть имя столбца первичного ключа
Вы не обязаны заполнять referencedColumnName
, если ссылочный объект имеет один столбец как PK, потому что нет сомнений в том, какой столбец он ссылается (т.е. идентификатор одного столбца Address
).
@ManyToOne
@JoinColumn(name="ADDR_ID")
public Address getAddress() { return address; }
Однако, если ссылочный объект имеет PK, который охватывает несколько столбцов, порядок, в котором вы указываете аннотации @JoinColumn
, имеет значение. Он может работать без указанного referencedColumnName
, но это просто повезло. Поэтому вы должны сопоставить его следующим образом:
@ManyToOne
@JoinColumns({
@JoinColumn(name="ADDR_ID", referencedColumnName="ID"),
@JoinColumn(name="ADDR_ZIP", referencedColumnName="ZIP")
})
public Address getAddress() { return address; }
или в случае ManyToMany
:
@ManyToMany
@JoinTable(
name="CUST_ADDR",
joinColumns=
@JoinColumn(name="CUST_ID"),
inverseJoinColumns={
@JoinColumn(name="ADDR_ID", referencedColumnName="ID"),
@JoinColumn(name="ADDR_ZIP", referencedColumnName="ZIP")
}
)
Пример реальной жизни
Два запроса, сгенерированные Hibernate из одного и того же сопоставления таблицы соединений, оба указаны без указанного столбца. Изменен только порядок аннотаций @JoinColumn
.
/* load collection Client.emails */
select
emails0_.id_client as id1_18_1_,
emails0_.rev as rev18_1_,
emails0_.id_email as id3_1_,
email1_.id_email as id1_6_0_
from client_email emails0_
inner join email email1_ on emails0_.id_email=email1_.id_email
where emails0_.id_client='2' and
emails0_.rev='18'
/* load collection Client.emails */
select
emails0_.rev as rev18_1_,
emails0_.id_client as id2_18_1_,
emails0_.id_email as id3_1_,
email1_.id_email as id1_6_0_
from client_email emails0_
inner join email email1_ on emails0_.id_email=email1_.id_email
where emails0_.rev='2' and
emails0_.id_client='18'
Мы запрашиваем таблицу соединений, чтобы получить клиентские письма. {2, 18}
- это составной идентификатор клиента. Порядок имен столбцов определяется порядком аннотаций @JoinColumn
. Порядок обоих целых чисел всегда один и тот же, вероятно, отсортированный по спящему режиму и поэтому требуется правильное выравнивание с столбцами таблицы соединений, и мы не можем или не должны полагаться на порядок сопоставления.
Интересно, что порядок целых чисел не соответствует порядку, в котором они отображаются в сущности - в этом случае я ожидал бы {18, 2}
. Поэтому кажется, что Hibernate сортирует имена столбцов, прежде чем использовать их в запросе. Если это верно, и вы бы заказали @JoinColumn
так же, как вам не нужно referencedColumnName
, но я говорю это только для иллюстрации.
Правильно заполненные атрибуты referencedColumnName
приводят к тому же запросу без двусмысленности, в моем случае второй запрос (rev = 2
, id_client = 18
).
Ответ 5
Для примера использования JPA 2.x для общего случая двух таблиц с однонаправленным соединением @OneToMany
см. https://en.wikibooks.org/wiki/Java_Persistence/OneToMany#Example_of_a_JPA_2.x_unidirectional_OneToMany_relationship_annotations
Снимок экрана из этой статьи JPA WikiBooks: Пример однонаправленной базы данных отношений OneToMany JPA 2.x