在JPA中,有一个名为referencedColumnName
的属性,可以在@JoinColumn, @PrimaryKeyJoinColumn
上设置这个设置背后的想法,有人可以举一个很好的例子来说明这个用途吗?
答案 0 :(得分:59)
将另一列指定为另一个表的默认 id 列,例如请考虑以下
TableA
id int identity
tableb_key varchar
TableB
id int identity
key varchar unique
// in class for TableA
@JoinColumn(name="tableb_key", referencedColumnName="key")
答案 1 :(得分:36)
“referencedColumnName”属性是表中要使用要循环的列进行引用的列的名称。或者以简短的方式:它是目标表中引用的列。想象一下这样的事情:汽车和人。一个人可以有很多车,但一辆车只属于一个人(对不起,我不喜欢别人开车)。
表人
name char(64)主键
age int桌车
car_registration char(32)主键
car_brand(char 64)
car_model(char64)
owner_name char(64)外键引用 Person(name)
当你实现类时,你会有类似
的东西class Person{
...
}
class Car{
...
@ManyToOne
@JoinColumn(columnName="owner_name", referencedColumnName="name")
private Person owner;
}
希望这有帮助。
答案 2 :(得分:19)
引用API on referencedColumnName:
此外键引用的列的名称 列。
默认值(仅在使用单个连接列时适用): 与引用表的主键列相同的名称。
何时使用?
当引用表中存在复合PK 时,您需要指定要引用的列名。
答案 3 :(得分:7)
name
属性指向包含asociation的列,即外键的列名referencedColumnName
属性指向isociated / referenced实体中的相关列,即主键的列名如果引用的实体将单列作为PK,则不需要填充referencedColumnName
,因为毫无疑问它引用了哪个列(即Address
单列ID)。
@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}
是客户端的复合ID。列名称的顺序由您@JoinColumn
注释的顺序决定。两个整数的顺序总是相同的,可能是通过hibernate排序的,这就是为什么需要与连接表列正确对齐的原因,我们不能或应该依赖映射顺序。
有趣的是整数的顺序与它们在实体中映射的顺序不匹配 - 在这种情况下,我希望{18, 2}
。因此,似乎Hibernate在查询中使用它们之前对列名称进行排序。如果这是真的,您可以按照您不需要@JoinColumn
的方式订购referencedColumnName
,但我这样做只是为了说明。
正确填充的referencedColumnName
属性会产生完全相同的查询而不会产生歧义,在我的情况下是第二个查询(rev = 2
,id_client = 18
)。
答案 4 :(得分:0)
对于两个表的一般情况的JPA 2.x示例用法,使用@OneToMany
单向连接,请参阅https://en.wikibooks.org/wiki/Java_Persistence/OneToMany#Example_of_a_JPA_2.x_unidirectional_OneToMany_relationship_annotations
此WikiBooks JPA文章的屏幕截图: Example of a JPA 2.x unidirectional OneToMany relationship database
答案 5 :(得分:0)
(可选)此外键引用的列的名称 列。
示例:
Dept
Long id;
String deptNo;
String name;
Employee
Long id;
String EmpNo;
String Name;
@JoinColumn(name = "dept", referencedColumnName = "deptNo")
Dept dept;