JPA:@联接列和@主键联接列之间区别?

fumotvh3  于 2022-11-24  发布在  其他
关注(0)|答案(4)|浏览(154)

@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的作用是什么?

u2nhd7ah

u2nhd7ah1#

如果我也将该列提升为/PK(也称为标识关系),会发生什么情况?由于该列现在是PK,我必须用@Id(...)标记它。
这种对派生标识符的增强支持实际上是JPA2.0中新增内容的一部分(请参阅JPA2.0规范中的2.4.1对应于派生标识的主键一节),JPA1.0不允许OneToOneManyToOne上有Id。必须使用PrimaryKeyJoinColumn并为外键列定义一个Basic``IdMap。
现在的问题是:@Id +@联接列是否仅与@主键联接列相同?
您可以获得类似的结果,但是在OneToOneManyToOne上使用Id要简单得多,并且是将派生标识符Map到JPA 2.0的首选方法。PrimaryKeyJoinColumn可能仍然用于JOINED继承策略中。下面是JPA 2.0规范中的相关部分:

11.1.40主键联接列注解

PrimaryKeyJoinColumn注解指定一个主键列,该列用作与另一个表连接得外键.
PrimaryKeyJoinColumn注解用于将JOINEDMap策略中的实体子类的主表连接到其超类的主表;它在SecondaryTable注解中用于将辅助表连接到主表;并且它可以用在OneToOneMap中,在OneToOneMap中,引用实体的主键被用作被引用实体的外键[108]。
...
如果在JOINEDMap策略中没有为子类指定PrimaryKeyJoinColumn注解,则会假定外键列与超类得主表得主键列具有相同得名称.
...

    • 示例:**客户与价值客户子类
@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]The derived id mechanisms described in section 2.4.1.1 are now to be preferred over PrimaryKeyJoinColumn for the OneToOne mapping case.

另请参阅

  • 通过一对一关系的主键

这个源代码http://weblogs.java.net/blog/felipegaucho/archive/2009/10/24/jpa-join-table-additional-state声明使用@ManyToOne和@Id可以与JPA1.x一起工作。现在谁是正确的?
作者正在使用EclipseLink的预发布JPA 2.0兼容版本(在本文发表时为2.0.0-M7版本)来编写一篇关于JPA 1.0的文章(!)。本文具有误导性,作者使用的是JPA 1.0的一部分。
为了记录在案,EclipseLink 1.1中增加了对OneToOneManyToOne上的Id的支持(请参阅来自James Sutherland的消息,EclipseLink委员会委员和Java Persistence wiki书籍的主要贡献者)。

lymgl2op

lymgl2op2#

我通常通过以下图表来区分这两者:
使用PrimaryKeyJoinColumn

使用JoinColumn

vaqhlq81

vaqhlq813#

我知道这是一篇老文章,但是如果您想要单向关系或者多个表共享同一个id,那么使用PrimaryKeyColumn是一个很好的时机。
一般来说,这是一个坏主意,最好使用JoinColumn的外键关系。
话虽如此,如果您正在使用一个使用类似这样的系统的旧数据库,那么这将是使用它的好时机。

z9smfwbn

z9smfwbn4#

当您想要管理(变更数据行名称、设定可为Null等等)目的实体数据表中的外部索引键数据行时,您可以使用@JoinColumn。在这里,Address数据表会包含与外部索引键类似的User数据表ID,但它的数据行将会是nameuser_id(@Sam YC的第二个配置)

@Entity
public class Address implements Serializable {

@Id
@GeneratedValue
private String id;

private String city;

@OneToOne(optional = false)
@JoinColumn(name = "user_id", updatable = false)
private User user;
}

当您想要使用参照实体的主索引键,就像目的实体的主索引键一样,您可以使用@PrimaryKeyJoinColumn。在这里,Address知道参照的User,但是Address数据表没有外部索引键数据行,因为它的id与User Id相同(@Sam YC的第一个配置)

@Entity
public class Address implements Serializable {

@Id
@GeneratedValue(generator = "foreignKeyGenerator")
@GenericGenerator(
        name = "foreignKeyGenerator",
        strategy = "foreign",
        parameters = @org.hibernate.annotations.Parameter(
                name = "property", value = "userT"
        )
)
private String id;
private String city;

@OneToOne(optional = false)
@PrimaryKeyJoinColumn
private User userT;
}

相关问题