Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA: difference between @JoinColumn and @PrimaryKeyJoinColumn?

What's the exact difference between @JoinColumn and @PrimaryKeyJoinColumn?

You use @JoinColumn for columns that are part of a foreign key. A typical column could look like (e.g. in a join table with additional attributes):

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

What happens if I promote the column to be a/the PK, too (a.k.a. identifying relationship)? As the column is now the PK, I must tag it with @Id:

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

Now the question is:

Are @Id + @JoinColumn the same as just @PrimaryKeyJoinColumn?:

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

If not, what's @PrimaryKeyJoinColumn there for?

like image 459
Kawu Avatar asked Aug 05 '10 16:08

Kawu


People also ask

What is @JoinColumn in JPA?

JPA JAVA EE. @JoinColumn is used to specify a column for joining an entity association or element collection. This annotation indicates that the enclosing entity is the owner of the relationship and the corresponding table has a foreign key column which references to the table of the non-owning side.

What is the use of @JoinColumn annotation?

Annotation Type JoinColumn. Specifies a column for joining an entity association or element collection. If the JoinColumn annotation itself is defaulted, a single join column is assumed and the default values apply. (Optional) The SQL fragment that is used when generating the DDL for the column.

Is @JoinColumn mandatory?

It is not necessary to have @JoinColumn annotation. You can always override it. If you won't provide it in your code then Hibernate will automatically generate one for you i.e. default name for your column. Could you please be more specific?


1 Answers

What happens if I promote the column to be a/the PK, too (a.k.a. identifying relationship)? As the column is now the PK, I must tag it with @Id (...).

This enhanced support of derived identifiers is actually part of the new stuff in JPA 2.0 (see the section 2.4.1 Primary Keys Corresponding to Derived Identities in the JPA 2.0 specification), JPA 1.0 doesn't allow Id on a OneToOne or ManyToOne. With JPA 1.0, you'd have to use PrimaryKeyJoinColumn and also define a Basic Id mapping for the foreign key column.

Now the question is: are @Id + @JoinColumn the same as just @PrimaryKeyJoinColumn?

You can obtain a similar result but using an Id on OneToOne or ManyToOne is much simpler and is the preferred way to map derived identifiers with JPA 2.0. PrimaryKeyJoinColumn might still be used in a JOINED inheritance strategy. Below the relevant section from the JPA 2.0 specification:

11.1.40 PrimaryKeyJoinColumn Annotation

The PrimaryKeyJoinColumn annotation specifies a primary key column that is used as a foreign key to join to another table.

The PrimaryKeyJoinColumn annotation is used to join the primary table of an entity subclass in the JOINED mapping strategy to the primary table of its superclass; it is used within a SecondaryTable annotation to join a secondary table to a primary table; and it may be used in a OneToOne mapping in which the primary key of the referencing entity is used as a foreign key to the referenced entity[108].

...

If no PrimaryKeyJoinColumn annotation is specified for a subclass in the JOINED mapping strategy, the foreign key columns are assumed to have the same names as the primary key columns of the primary table of the superclass.

...

Example: Customer and ValuedCustomer subclass

@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.

See also

  • Primary Keys through OneToOne Relationships

This source http://weblogs.java.net/blog/felipegaucho/archive/2009/10/24/jpa-join-table-additional-state states that using @ManyToOne and @Id works with JPA 1.x. Who's correct now?

The author is using a pre release JPA 2.0 compliant version of EclipseLink (version 2.0.0-M7 at the time of the article) to write an article about JPA 1.0(!). This article is misleading, the author is using something that is NOT part of JPA 1.0.

For the record, support of Id on OneToOne and ManyToOne has been added in EclipseLink 1.1 (see this message from James Sutherland, EclipseLink comitter and main contributor of the Java Persistence wiki book). But let me insist, this is NOT part of JPA 1.0.

like image 53
Pascal Thivent Avatar answered Oct 05 '22 15:10

Pascal Thivent