This post will walk you through the steps of mapping a JPA/Hibernate Many to Many bidirectional relationship with Spring Boot, Spring Data JPA, Lombok, 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'll need
- Docker CE 18+
Project structure
Project dependencies
Many-To-Many Relationship
Many-to-many relationship refers to the relationship between two entities/tables A and B in which one element/row of A may be linked with many elements of B, and vice versa, one member of B may be linked to many elements of A.
In this example, the book
and publisher
tables have a many-to-many relationship. One book may be published by many publishers and one publisher may publish many books.
book_publisher
is a join table of book
and publisher
.
book_publisher.book_id
is a foreign key references to book.id
, book_publisher.publisher_id
is a foreign key references to publisher.id
.
book_id
and publisher_id
is also a composite primary key of book_publisher
.
Try this example if the join table has extra columns beside two foreign keys JPA/Hibernate Many To Many Extra Columns Example of Bidirectional Relationship Mapping
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.
@ManyToMany
defines a many-to-many relationship between 2 entities. mappedBy
indicates the entity is the inverse of the relationship.
@JoinTable
defines the join table of 2 associated entities. If the JoinTable
annotation is missing, the default values of the annotation elements apply. The name of the join table is assumed to be the table names of the associated primary tables concatenated together (owning side first) using an underscore.
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 Publisher
will be saved at the same time with Book
without the need of calling its save function explicitly.
Testing time
Prepare 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 many-to-many
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 the 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/many-to-many
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