JPA:@JoinColumn 和 @PrimaryKeyJoinColumn 之间的区别?
Posted
技术标签:
【中文标题】JPA:@JoinColumn 和 @PrimaryKeyJoinColumn 之间的区别?【英文标题】:JPA: difference between @JoinColumn and @PrimaryKeyJoinColumn? 【发布时间】:2011-03-25 22:20:03 【问题描述】:@JoinColumn
和 @PrimaryKeyJoinColumn
之间的确切区别是什么?
您将@JoinColumn
用于作为外键一部分的列。典型的列可能如下所示(例如,在具有附加属性的连接表中):
@ManyToOne
@JoinColumn(name = "...")
private OtherClass oc;
如果我也将该列提升为 PK(也称为识别关系),会发生什么情况?由于该列现在是PK,我必须用@Id
标记它:
@Id
@ManyToOne
@JoinColumn(name = "...")
private OtherClass oc;
现在的问题是:
@Id
+ @JoinColumn
和 @PrimaryKeyJoinColumn
一样吗?:
@ManyToOne
@PrimaryKeyJoinColumn(name = "...")
private OtherClass oc;
如果不是,那@PrimaryKeyJoinColumn
是干什么用的?
【问题讨论】:
【参考方案1】:如果我也将该列提升为 PK(也称为识别关系),会发生什么情况?由于该列现在是 PK,我必须用 @Id (...) 标记它。
这种对派生标识符的增强支持实际上是new stuff in JPA 2.0 的一部分(请参阅JPA 2.0 规范中的2.4.1 与派生标识符对应的主键部分) , JPA 1.0 不允许在 OneToOne
或 ManyToOne
上使用 Id
。使用 JPA 1.0,您必须使用 PrimaryKeyJoinColumn
并为外键列定义 Basic
Id
映射。
现在的问题是:@Id + @JoinColumn 和 @PrimaryKeyJoinColumn 一样吗?
您可以获得类似的结果,但在OneToOne
或ManyToOne
上使用Id
会简单得多,并且是使用 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] 派生的id机制 现在在第 2.4.1.1 节中描述 优先于
PrimaryKeyJoinColumn
为 OneToOne 映射案例。
另见
Primary Keys through OneToOne Relationships此来源http://weblogs.java.net/blog/felipegaucho/archive/2009/10/24/jpa-join-table-additional-state 声明使用@ManyToOne 和@Id 可用于JPA 1.x。现在谁是正确的?
作者正在使用 EclipseLink 的预发布 JPA 2.0 兼容版本(发文时版本为 2.0.0-M7)来撰写有关 JPA 1.0(!) 的文章。这篇文章具有误导性,作者使用的东西不是 JPA 1.0 的一部分。
作为记录,EclipseLink 1.1 中添加了对 OneToOne
和 ManyToOne
的支持(参见 this message 来自 James Sutherland,EclipseLink 提交者和 Java Persistence 维基书的主要贡献者)。但让我坚持,这不是 JPA 1.0 的一部分。
【讨论】:
此来源 weblogs.java.net/blog/felipegaucho/archive/2009/10/24/… 声明使用 @ManyToOne 和 @Id 可用于 JPA 1.x。现在谁是对的? 好的。感谢您清除它。我是对的,a 提到的坏例子错误地使用了@IdClass? @Id 注释不应该放在实体类中的单独(冗余/重复)列中正确吗? (尽管我知道不再推荐使用@IdClass) 我的意思是,类中应该有两个属性:@Id @Column private String机构;和@Id @Column 私有字符串竞争;只是为了指定PK对吗? @Kawu 很抱歉,但老实说,在一个小评论框中讨论这个问题太难了。我什至不确定我是否理解你在说什么。如果您还有其他具体问题,我建议您选择一个 JPA 实现并进行一些试验,或者发布一个带有完整示例(和 JPA 版本)的 new 问题。这会让事情变得更容易。【参考方案2】:我通常通过这张图区分这两者:
使用PrimaryKeyJoinColumn
使用JoinColumn
【讨论】:
@yusher,PrimaryKeyJoinColumn
使用相同的主键值连接两个表,JoinColumn
,主表的主键将成为另一个表的外键。【参考方案3】:
我知道这是一篇旧帖子,但如果您想要一个单向关系或多个表都共享相同的 ID,那么使用 PrimaryKeyColumn
的好时机。
一般来说这是一个坏主意,最好使用与JoinColumn
的外键关系。
话虽如此,如果您正在处理使用此类系统的旧数据库,那么这将是使用它的好时机。
【讨论】:
以上是关于JPA:@JoinColumn 和 @PrimaryKeyJoinColumn 之间的区别?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用查询而不是带有 JPA 的 @JoinColumn 映射实体关联?
当我使用两个表实体时如何在 JPA @JoinColumn 中指定忽略大小写
使用 joinColumn 而不是 mappedBy 有啥危害?
jpa hibernate @OneToOne @JoinColumn referencedColumnName 被忽略