Hibernate - Many to Many
An 'Employee' can be assigned to many 'Project'. At the same time a 'Project' can also have multiple 'Employee' objects or employees.
If we see this from a database perspective, it is considered to be a 'Many to Many' relationship.
Let us see, how we can achieve a 'Many to Many' relationship using Hibernate.
Let us see the 'Employee' class:
class Employee {
String id;
String name;
Set <Project> projectSet = new HashSet <Project>();
---Getters & Setters---
}
An 'Employee' can be assigned to various 'Project'. So, in the 'Employee' class we have put:
Set <Project> projectSet = new HashSet <Project>();
The 'Project' class is defined below.
class Project{
int projectId;
String projectName;
Set <Employee> employeeSet = new HashSet <Employee>();
---Getters & Setters---
}
Since a 'Project' can have multiple 'Employee' objects. We have used a 'List' below:
Set <Employee> employeeSet = new HashSet <Employee>();
Let us follow the below steps for a 'Many to Many' mapping in Hibernate.
1. Firstly in 'Employee.hbm.xml' mapping file we need to tell Hibernate that 'Employee' and 'Project' are having a 'Many to Many' relationship.
Employee.hbm.xml
<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name = "Employee" table = "EMPLOYEE">
<id name = "id" type = "string">
<column name = "ID">
</id>
<property name = "name" type = "string">
<column name = "NAME">
</property>
<set name = "projectSet" inverse="false" cascade="all">
<key column = "ID"/>
<many-to-many class="Project" column="PROJECT_ID"/>
</set>
</class>
</hibernate-mapping>
We have used <many-to-many> tag to create a 'Many to Many' relationship between 'EMPLOYEE' and 'PROJECT'.
We have used '<set>' tag to mention the 'Set' of objects(i.e. Project) in 'Employee' class.
<set name = "projectSet" inverse="false" cascade="all">
And the key Column is the primary key of 'EMPLOYEE' table. Which is used to create the relationship between 'EMPLOYEE' and 'PROJECT' table.
Finally, we have the <many-to-many> tag defining Many to Many relationship with the 'Project' class and its associated primary key 'PROJECT_ID'.
<many-to-many class="Project" column="PROJECT_ID"/>
2. Next, let's write the 'Project.hbm.xml' mapping file:
Project.hbm.xml
<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name = "Project" table = "PROJECT">
<id name = "projectId" type = "string">
<column name = "PROJECT_ID">
</id>
<property name = "projectName" type = "string">
<column name = "PROJECT_NAME">
</property>
<set name = "projectSet" inverse="false" cascade="all">
<key column = "PROJECT_ID"/>
<many-to-many class="Project" column="ID"/>
</set>
</class>
</hibernate-mapping>
The above mapping is just the same as 'Employee.hbm.xml'. Where we have mentioned the 'Project' class in <many-to-many> mapping file.
3. Now that we have defined the mapping files for the Entities 'Employee' and 'Project', we will be writing the main class where we will be saving the 'Employee' data and its corresponding 'Project' data to the database using Hibernate.
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateSave {
public static void main(String[] args) {
static SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
Set <Project> projectSet = new Set <Project>();
Project projectPhills = new Project();
projectPhills.setProjectId("A001");
projectPhills.setProjectName("Phills Project");
projectSet.add(projectPhills);
Project projectONeal = new Project();
projectONeal.setProjectId("B001");
projectONeal.setProjectName("O Neals Project");
projectSet.add(projectONeal);
Employee employee = new Employee();
employee.setId(1);
employee.setName("Joe");
employee.setProjectSet(projectSet);
session.save(employee);
session.getTransaction().commit();
session.close();
sessionFactory.close();
}
}
So, in the above example we have created two 'Project' objects.
First for a project 'Phills Project'
Project projectPhills = new Project();
projectPhills.setProjectId("A001");
projectPhills.setProjectName("Phills Project");
Second for a project 'O Neals Project'.
Project projectONeal = new Project();
projectONeal.setProjectId("B001");
projectONeal.setProjectName("O Neals Project");
And since the Projects are stored in 'Set'. We have created a 'Set' object
Set <Project> projectSet = new Set <Project>();
projectSet.add(projectPhills);
projectSet.add(projectONeal);
And finally we have added the Set 'projectSet' to the 'Project' object.
employee.setProjectSet(projectSet);
session.save(employee);
EMPLOYEE
PROJECT
PROJECT_ID |
PROJECT_NAME |
A001 |
Phills Project |
B001 |
O Neals Project |
EMPLOYEE_PROJECT
ID |
PROJECT_ID |
1 |
A001 |
1 |
B001 |
So as we see, to maintain the relationship among the tables hibernate has created a new table 'EMPLOYEE_PROJECT' which contains only the keys from both the tables and establishes a relationship.