This tutorial will walk you through the steps of mapping a JPA/Hibernate One to One shared primary key bidirectional relationship with Spring Boot, Spring Data JPA, MySQL and Docker.

JPA/Hibernate Entity Bidirectional Relationship Mapping Example Series with Spring Boot and MySQL
- JPA/Hibernate Composite Primary Key Example
- JPA/Hibernate One To One Bidirectional Relationship Mapping
- JPA/Hibernate One To One Shared Primary Key Bidirectional Relationship Mapping
- JPA/Hibernate One To Many Bidirectional Relationship Mapping
- JPA/Hibernate Many To Many Bidirectional Relationship Mapping
- JPA/Hibernate Many To Many Extra Columns Bidirectional Relationship Mapping
- Handling Circular Reference of JPA/Hibernate Entity Bidirectional Relationships with Jackson JsonIgnoreProperties
- JPA/Hibernate CRUD Example, Deleting Data with JPQL, CascadeType, and orphanRemoval
- Database Migration/Evolution Example with Flyway and JPA/Hibernate

What you will need

  • Docker CE 18+

Project structure

Project dependencies


One-To-One Shared Primary Key Relationship

One to one relationship refers to the relationship between two entities/tables A and B in which one item/row of A may be linked with only one item/row of B, and vice versa.

In this example, book and book_detail tables have a one-to-one relationship. A book has only one book detail, and a book detail belong to only one book.

book_detail.book_id is a foreign key references to book.id. book_detail also uses its foreign key book_id as primary key so-called shared primary key.

Define JPA Entities

JPA Entity is defined with @Entity annotation, represent a table in your database.



@Id declares the entity identifier.

@Column maps the entity's field with the table's column. If @Column is omitted, the field name of the entity will be used as column name by default.

@OneToOne defines a one-to-one relationship between 2 entities.

@JoinColumn defines foreign key column and indicates the owner of the relationship.

mappedBy indicates the inverse of the relationship.

@MapsId defines embedded primary key, book_detail.book_id is embedded from book.id.

Spring Data JPA Repository

Spring Data JPA contains some built-in Repository abstracting common functions based on EntityManager to work with database such as findAll, findById, save, delete, deleteById. All we need for this example is extends JpaRepository.



Application Properties


spring.jpa.hibernate.ddl-auto=create allows JPA/Hibernate auto create database and table schema for you.

On production environment, you may like to disable the DDL Auto feature by using spring.jpa.hibernate.ddl-auto=validate or spring.jpa.hibernate.ddl-auto=none (default). Check out this example as one of the approaches
Database Migration/Evolution Example with Flyway and JPA/Hibernate

Creating data with JPA/Hibernate

Thanks to CascadeType.ALL, associated entity BookDetail will be saved at the same time with Book without the need of calling its save function explicitly


Testing time

Preparing Dockerfile for Java/Spring Boot application


Start your application and infrastructure via Docker Compose. Make sure your local Docker is running and your bash console is at the springboot-examples project root directory.

docker-compose -f docker-compose-jpa.yaml up --renew-anon-volumes one-to-one-shared-primary-key

Access to MySQL Server docker container by issuing below bash command and key in hellokoding on Enter password:

docker exec -it hk-mysql mysql -p

Query schema and data created by JPA/Hibernate based on your mapping

That's it! Thanks for joining and have a happy coding. You can find the full source code as below

Source code

https://github.com/hellokoding/springboot-examples/tree/master/jpa-hibernate/one-to-one-shared-primary-key

You may also like
- Handling Circular Reference of JPA/Hibernate Entity Bidirectional Relationships with Jackson JsonIgnoreProperties
- JPA/Hibernate CRUD Example, Deleting Data with JPQL, CascadeType, and orphanRemoval