How to change the @OneToOne shared primary key column name with JPA and Hibernate

Imagine having a tool that can automatically detect JPA and Hibernate performance issues. Hypersistence Optimizer is that tool!


In this article, we are going to see how you can change the @OneToOne shared primary key column name when using JPA and Hibernate. This has been a recurrent theme when answering questions about Hibernate or during my High-Performance Java Persistence training.

As previously explained, the one-to-one database table relationship requires the Primary Key to be shared among the parent and the child tables.

Unfortunately, just adding the JPA @OneToOne annotation in the child entity does not render a true one-to-one table relationship since a separate Foreign Key column will be used. Only when adding the @MapsId annotation will the JPA one-to-one association map to a real one-to-one table relationship.

Domain Model

Let’s assume we are using the following Post and PostDetails entities:

OneToOne JPA relationship

The Post entity is the parent while the PostDetails is the child entity and its associated Primary Key is also a Foreign Key to the parent table Primary Key.

The Post entity is rather straightforward to map since it does not contain any association:

@Entity(name = "Post")
@Table(name = "post")
public class Post {

    private Long id;

    private String title;

    //Getters and setters omitted for brevity

The PostDetails can be mapped as follows:

@Entity(name = "PostDetails")
@Table(name = "post_details")
public class PostDetails {

    private Long id;

    @Column(name = "created_on")
    private Date createdOn;

    @Column(name = "created_by")
    private String createdBy;

    @OneToOne(fetch = FetchType.LAZY)
    private Post post;

    public PostDetails() {}

    public PostDetails(String createdBy) {
        createdOn = new Date();
        this.createdBy = createdBy;

    //Getters and setters omitted for brevity

Notice that we are using FetchType.LAZY explicitly since, by default, JPA uses DetchType.EAGER for @OneToOne and @ManyToOne associations, and that’s very bad for performance.

When generating the schema with the hbm2ddl tool or if we create the schema manually and managing it with Flyway, Hibernate expects the following database table structure:

One-to-one table relationship with default Primary Key column name

Notice that the Primary Key column name is called post_id in the post_details table, and this is not very nice since the Primary Key column name is called id in the post table.

@JoinColumn to the rescue

To fix this issue, we just have to add a @JoinColumn annotation to the @OneToOne association in the PostDetails entity:

@JoinColumn(name = "id")
private Post post;

This way, Hibernate will either generate or expect the following database tables:

One-to-one table relationship with custom Primary Key column name

Awesome, right?

I'm running an online workshop on the 27th of May about High-Performance SQL.

If you enjoyed this article, I bet you are going to love my Book and Video Courses as well.


It’s a little bit unfortunate that, by default, the @MapsId annotation does not use the entity identifier name to match the underlying table Primary Key column. However, using the @JoinColumn annotation a straightforward way to fix this issue.

Transactions and Concurrency Control eBook

2 Comments on “How to change the @OneToOne shared primary key column name with JPA and Hibernate

  1. What if there exist a table post_details with primary key id column and post_id column ( foreignkey) with data but initaily not using @MapsId, after changing to @MapsId and setting @JoinColumn(name = “post_id”) ? will it shows the same behaviour of lazy loading as you described above ? In this case it’s not possible to change id column of post_id as it cause inconsistency of previous data. Is there any posibility of lazy loding in above situation ?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

High-Performance SQL Online Workshop - 27th of May