JPA:@JoinColumn和@PrimaryKeyJoinColumn之间的区别?


82

@JoinColumn和之间的确切区别是@PrimaryKeyJoinColumn什么?

您使用@JoinColumn的列是外键的一部分。典型的列可能看起来像(例如,在具有附加属性的联接表中):

@ManyToOne
@JoinColumn(name = "...")
private OtherClass oc;

如果我也将列也提升为a / PK(又称为识别关系)会怎样?由于该列现在是PK,因此我必须用标记@Id

@Id
@ManyToOne
@JoinColumn(name = "...")
private OtherClass oc;

现在的问题是:

@Id+@JoinColumn上面一样@PrimaryKeyJoinColumn

@ManyToOne
@PrimaryKeyJoinColumn(name = "...")
private OtherClass oc;

如果没有,那@PrimaryKeyJoinColumn有什么用?

Answers:


53

如果我也将该列也提升为a / PK(又称为识别关系)会怎样?由于该列现在是PK,因此我必须使用@Id(...)对其进行标记。

派生标识符的增强支持实际上是JPA 2.0中新内容的一部分(请参阅JPA 2.0规范中的2.4.1与派生身份相对应的主键部分),JPA 1.0不允许IdOneToOne或上使用ManyToOne。在JPA 1.0中,您必须使用外键列PrimaryKeyJoinColumnBasic Id为其定义一个映射。

现在的问题是:@Id + @JoinColumn与@PrimaryKeyJoinColumn是否相同?

可以得到类似的结果,但使用IdOneToOneManyToOne简单得多,并且是衍生识别符与JPA 2.0映射的首选方式。PrimaryKeyJoinColumn仍可以在JOINED继承策略中使用。在JPA 2.0规范的相关部分下面:

11.1.40 PrimaryKeyJoinColumn注释

PrimaryKeyJoinColumn批注指定用作外键加入到另一个表的主键列。

PrimaryKeyJoinColumn注释用于连接在一个实体子类的主表JOINED 映射策略到它的父类的主表; 它在 SecondaryTable注释中用于将辅助表连接到主表;并且它可以在OneToOne 映射中使用,在该映射中引用实体的主键用作被引用实体的外键[108]

...

如果PrimaryKeyJoinColumn 在JOINED映射策略中未为子类指定注释,则假定外键列的名称与超类主表的主键列的名称相同。

...

示例: Customer和ValuedCustomer子类

@Entity
@Table(name="CUST")
@Inheritance(strategy=JOINED)
@DiscriminatorValue("CUST")
public class Customer { ... }

@Entity
@Table(name="VCUST")
@DiscriminatorValue("VCUST")
@PrimaryKeyJoinColumn(name="CUST_ID")
public class ValuedCustomer extends Customer { ... }

[108]对于OneToOne映射情况,现在将首选2.4.1.1节中描述的派生id机制 PrimaryKeyJoinColumn

也可以看看


此源http://weblogs.java.net/blog/felipegaucho/archive/2009/10/24/jpa-join-table-additional-state指出使用@ManyToOne和@Id可与JPA 1.x一起使用。现在谁是正确的?

作者使用的是与JPA 2.0兼容的预发行版EclipseLink(在撰写本文时为2.0.0-M7版)来撰写有关JPA 1.0(!)的文章。本文具有误导性,作者使用的不是JPA 1.0的一部分。

作为记录,在EclipseLink 1.1中添加了IdonOneToOne和的支持ManyToOne(请参阅James Pertherland的此消息James Sutherland是EclipseLink的发起者和Java Persistence Wiki书的主要贡献者)。但请允许我坚持,这不是JPA 1.0的一部分。


此源 weblogs.java.net/blog/felipegaucho/archive/2009/10/24/… 指出,使用@ManyToOne和@Id可与JPA 1.x一起使用。现在谁是正确的?
卡乌(Kawu)2010年

好。感谢您清理。我对被引用的错误示例错误地使用@IdClass是正确的吗?@Id注释不应该放在实体类的单独(冗余/重复)列中正确吗?(即使我知道不再建议使用@IdClass)
Kawu 2010年

我的意思是,该类中应该有两个属性:@Id @Column private String制度;和@Id @Column私有String竞赛;只是为了指定PK吧?
卡乌(Kawu)2010年

@Kawu对不起,但老实说,在一个小的评论框中讨论这个问题太难了。我什至不确定我是否理解您的意思。如果您还有其他特定问题,建议您选择一个JPA实施并进行一些试验,或者发布带有完整示例(和JPA版本)的问题。这会使事情变得容易得多。
Pascal Thivent 2010年

37

我通常通过此图来区分这两个:

使用 PrimaryKeyJoinColumn

在此处输入图片说明

使用 JoinColumn

在此处输入图片说明


2
@yusher,PrimaryKeyJoinColumn使用相同的主键值连接两个表,并且JoinColumn,主表的主键将成为另一个表中的外键。
山姆YC

2

我知道这是一篇过时的文章,但是PrimaryKeyColumn如果您需要单向关系或有多个共享相同ID的表,那么最好使用它。

通常,这不是一个好主意,并且最好将外键关系与一起使用JoinColumn

话虽如此,如果您正在使用这样的系统的旧数据库上工作,那将是使用它的好时机。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.