[java] 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?

This question is related to java hibernate jpa jakarta-ee identifying-relationship

The answer is


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


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.


I normally differentiate these two via this diagram:

Use PrimaryKeyJoinColumn

enter image description here

Use JoinColumn

enter image description here


I know this is an old post, but a good time to use PrimaryKeyColumn would be if you wanted a unidirectional relationship or had multiple tables all sharing the same id.

In general this is a bad idea and it would be better to use foreign key relationships with JoinColumn.

Having said that, if you are working on an older database that used a system like this then that would be a good time to use it.


Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to hibernate

Hibernate Error executing DDL via JDBC Statement How does spring.jpa.hibernate.ddl-auto property exactly work in Spring? Error creating bean with name 'entityManagerFactory' defined in class path resource : Invocation of init method failed JPA Hibernate Persistence exception [PersistenceUnit: default] Unable to build Hibernate SessionFactory Disable all Database related auto configuration in Spring Boot Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] HikariCP - connection is not available Hibernate-sequence doesn't exist How to find distinct rows with field in list using JPA and Spring? Spring Data JPA and Exists query

Examples related to jpa

No converter found capable of converting from type to type How does spring.jpa.hibernate.ddl-auto property exactly work in Spring? Deserialize Java 8 LocalDateTime with JacksonMapper Error creating bean with name 'entityManagerFactory' defined in class path resource : Invocation of init method failed How to beautifully update a JPA entity in Spring Data? JPA Hibernate Persistence exception [PersistenceUnit: default] Unable to build Hibernate SessionFactory How to return a custom object from a Spring Data JPA GROUP BY query How to find distinct rows with field in list using JPA and Spring? What is this spring.jpa.open-in-view=true property in Spring Boot? Spring Data JPA and Exists query

Examples related to jakarta-ee

Java 11 package javax.xml.bind does not exist javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure The type java.io.ObjectInputStream cannot be resolved. It is indirectly referenced from required .class files Deploying Maven project throws java.util.zip.ZipException: invalid LOC header (bad signature) web.xml is missing and <failOnMissingWebXml> is set to true WELD-001408: Unsatisfied dependencies for type Customer with qualifiers @Default Name [jdbc/mydb] is not bound in this Context An internal error occurred during: "Updating Maven Project". java.lang.NullPointerException How to consume a SOAP web service in Java java.lang.ClassNotFoundException: com.sun.jersey.spi.container.servlet.ServletContainer

Examples related to identifying-relationship

JPA: difference between @JoinColumn and @PrimaryKeyJoinColumn? What's the difference between identifying and non-identifying relationships?