This tutorial will walk you through the steps of mapping a JPA and Hibernate Many to Many extra columns bidirectional entity relationships example with Spring Boot, Spring Data JPA, Lombok, MySQL and Docker
What you will need
- JDK 8+ or OpenJDK 8+
- Maven 3+
- MySQL Server 5+ or Docker CE 18+
Init project structure and dependencies
├── src │ └── main │ ├── java │ │ └── com │ │ └── hellokoding │ │ ├── jpa │ │ │ ├── book │ │ │ │ ├── Book.java │ │ │ │ ├── BookPublisher.java │ │ │ │ ├── BookRepository.java │ │ │ │ ├── Publisher.java │ │ │ │ └── PublisherRepository.java │ │ │ └── JpaApplication.java │ │ └── springboot │ └── resources │ └── application.properties ├── Dockerfile ├── docker-compose.yml └── pom.xml
Define JPA Entities and Repositories
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
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_publisher.book_id is a foreign key references to
book_publisher.publisher_id is a foreign key references to
publisher_id is also a composite primary key of
Beside 2 foreign key columns, the join table
book_publisher also has extra column
Try this example if the join table has no extra columns JPA/Hibernate Many To Many Example of Bidirectional Relationship Mapping
Define JPA and Hibernate 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.
@ManyToOne defines a one-to-many relationship between 2 entities.
@JoinColumn indicates the entity is the owner of the relationship and the corresponding table has a column with a foreign key to the referenced table.
mappedBy indicates the entity is the inverse of the relationship.
Spring Data JPA Repository
Spring Data JPA contains some built-in
Repository abstracting common functions based on
EntityManager to work with database such as
deleteById. All we need for this example is
Define properties and creating data
hk-mysql refers to Docker Compose service defined in the below
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 and Hibernate
CascadeType.ALL, associated entity
BookPublisher will be saved at the same time with
Book without the need of calling its save function explicitly.
Run the example
Run with Docker
Prepare Dockerfile for Java/Spring Boot application and docker-compose.yml for MySQL Server
Type the below command at the project root directory, make sure your local Docker is running
Access to MySQL Server docker container by issuing below bash command and key in
docker exec -it hk-mysql mysql -p
Query the schema and data created by JPA/Hibernate based on your mapping.
Run with JDK/OpenJDK, Maven and MySQL Server local
localhost and type the below command at the project root directory
mvn clean spring-boot:run