在JPA中,有一个名为的属性referencedColumnName
,可以根据该设置的@JoinColumn, @PrimaryKeyJoinColumn
含义设置该属性,有人可以举例说明可以在何处使用它吗?
Answers:
“ referencedColumnName”属性是您要注释的表中正在引用的表中的列的名称。或简而言之:这是目标表中引用的列。想象一下这样的事情:汽车和人。一个人可以拥有许多汽车,但一辆汽车仅属于一个人(对不起,我不喜欢其他人驾驶我的汽车)。
表人员
名称char(64)主键
年龄int表Car
car_registration char(32)主键
car_brand(字符64)
car_model(char64)
owner_name char(64)外键引用Person(name)
当您实现类时,您将获得类似
class Person{
...
}
class Car{
...
@ManyToOne
@JoinColumn([column]name="owner_name", referencedColumnName="name")
private Person owner;
}
编辑:正如@ searchengine27所评论的那样,columnName
在Java7文档的持久性部分中作为字段不存在。我不记得从何处获取此属性,但是我记得使用它,这就是为什么我将其留在示例中的原因。
columnName
不是注释的字段...
columnName
未在java7规范或java6中定义(这是我在回答此问题时所使用的版本)。这样看来您是对的
此外键列引用的列的名称。
缺省值(仅在使用单个连接列的情况下适用):与引用表的主键列相同的名称。
将在哪里使用?
如果被引用的表中有一个复合PK,那么您需要指定要引用的列名。
@ManyToMany
映射中有中间表时。
name
属性指向包含关联的列,即外键的列名referencedColumnName
属性指向关联/引用实体中的相关列,即主键的列名referencedColumnName
如果所引用的实体具有单个列作为PK,则不需要填写,因为毫无疑问,它引用的是哪个列(即,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
注释的顺序确定。两个整数的顺序总是相同的,可能是按休眠方式排序的,这就是为什么需要与联接表列正确对齐的原因,而我们不能也不应该依赖映射顺序。
有趣的是,整数的顺序与在实体中映射整数的顺序不匹配-在这种情况下,我希望如此{18, 2}
。因此,Hibernate似乎正在对列名称进行排序,然后才在查询中使用它们。如果是这样,您将以@JoinColumn
不需要的方式订购referencedColumnName
,但我仅出于说明目的而说。
正确填写referencedColumnName
属性导致无歧义完全相同的查询,在我的情况下,第二个查询(rev = 2
,id_client = 18
)。
有关两个表的一般情况的JPA 2.x示例用法(具有@OneToMany
单向联接),请参见https://en.wikibooks.org/wiki/Java_Persistence/OneToMany#Example_of_a_JPA_2.x_unidirectional_OneToMany_relationship_annotations
WikiBooks JPA文章的屏幕快照: JPA 2.x单向OneToMany关系数据库的示例