Hibernate Many To Many Tutorial
Introduction:
In this tutorial, we’ll learn to define and use a many-to-many entity association using Hibernate @ManyToMany annotation.
Context BuildUp:
To follow along with this tutorial, let’s say we have two entities – Employee and Qualification:
As we know, one employee can multiple qualifications. Also, there can be N number of employees with a specific qualification. It clearly means that the Employee and Qualificationentities share a Many-to-Many relationship.
Maven Dependencies:
In our POM, let’s first ensure we have the required dependencies:
<dependencies> ... <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.4.0.Final</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.13</version> </dependency> ... </dependencies>
We can always find out the latest available version at the Maven Central. Also, we’re using MySQL database for this tutorial.
Database Setup:
To represent a ManyToMany association, we’ll at least need three database tables. So, let’s say we have the below ERD diagram representing our database:
Also, let’s create our tables:
CREATE TABLE employee ( emp_id INT(15) NOT NULL AUTO_INCREMENT, first_name VARCHAR(20) DEFAULT NULL, last_name VARCHAR(20) DEFAULT NULL, PRIMARY KEY (emp_id) ); CREATE TABLE qualification ( qualification_id INT(15) NOT NULL AUTO_INCREMENT, title VARCHAR(20) DEFAULT NULL, PRIMARY KEY (qualification_id) ); CREATE TABLE employee_qualification ( emp_id INT(15) NOT NULL, qualification_id INT(15) NOT NULL, PRIMARY KEY (emp_id, qualification_id), CONSTRAINT employee_qualification_empIdFk FOREIGN KEY (emp_id) REFERENCES employee(emp_id), CONSTRAINT employee_qualification_qualIdFk FOREIGN KEY (qualification_id) REFERENCES qualification (qualification_id) );
Creating Entities:
Now that we have our database setup ready, let’s first create the model class – Employee:
@Entity @Table(name = "Employee") public class Employee { // ... @ManyToMany(cascade = { CascadeType.ALL }) @JoinTable( name = "Employee_Qualification", joinColumns = { @JoinColumn(name = "emp_id") }, inverseJoinColumns = { @JoinColumn(name = "qualification_id") } ) Set<Qualification> qualifications = new HashSet<>(); ... }
A Many-to-Many association has two sides – the owning and the inverse/referencing side. The actual physical mapping to the database is specified on the owning side of the relationship. Here, Employee is the owning entity and so we have used the @JoinTableannotation to define the actual physical database mapping. The @JoinTable annotation defines our employee_qualification join table.
The @JoinColumn annotation specifies the column that’ll be used to join the tables. We have also mentioned that qualification_id would be the inverse join column. It simply means it refers to the inverse side of the relationship which is our Qualification class.
Let’s now define our Qualification entity class:
@Entity @Table(name = "Qualification") public class Qualification { // ... @ManyToMany(mappedBy = "qualifications") private Set<Employee> employees = new HashSet<>(); ... }
Since Qualification class is the referencing or the inverse side of the association, we have used the mappedBy attribute to refer to its owning side (Employee).
Also as we can see, we have used @ManyToMany annotation in both of our entities.
Using Many-To-Many Association:
In our main() method, we can test out the above mapping:
//In our MainApp class public static void main(String[] args) { Session session = null; try { SessionFactory factory = new Configuration() .configure().buildSessionFactory(); session = factory.openSession(); Transaction tranx = session.beginTransaction(); Employee james = new Employee(1001, "James", "Allen"); Employee selena = new Employee(1002, "Selena", "Gomez"); Set<Employee> employees = new HashSet<>(); employees.add(james); employees.add(selena); Qualification masters = new Qualification(8787, "Masters Degree"); masters.setEmployees(employees); session.save(masters); tranx.commit(); } catch(Exception e) { e.printStackTrace(); } finally { if(session != null) session.close(); } }
On executing the above code, our test data would have been inserted in our employee, qualification and employee_qualification tables.
Conclusion:
In this mini-tutorial, we looked at how to establish a ManyToMany JPA association. We have used JPA annotations over the plain-old XML configurations as they are more convenient to use and are becoming increasingly popular.
Published on Java Code Geeks with permission by Shubhra Srivastava, partner at our JCG program. See the original article here: Hibernate Many To Many Tutorial Opinions expressed by Java Code Geeks contributors are their own. |
Hi,
Can you just clarify what the mappedBy annotation below refers to:
@ManyToMany(mappedBy = “qualifications”)
private Set employees = new HashSet();
Is it referring the instance variable of Employee class i.e.
public class Employee {
…
Set qualifications
?
Thanks in advance
Yes, you are right!
mappedBy specifies the relationship field or property of the owning entity