How to create One to Many and Many to One mapping between two database tables using hibernate?

Introduction

In this type of mapping, single data of one table relates with multiple data of second table or vice-versa. Once OneToMany and ManyToOne relationship is defined between two tables, is called bi-directional mapping.

Objective:

To learn, How to create One to Many Mapping

To learn, How to create Many to One Mapping

Mapping in Detail:

One to Many Mapping: A single attribute of a table relating with multiple attributes of another table is referred as One to Many mapping. Ex.: A department may have multiple employees.

Figure 1: One to Many Mapping

In One to Many Mapping implementation, Department Object will be referenced in the Employee entity class by collection and in order to define a One to Many mapping relationship, annotation @OneToMany is used as follows:

@OneToMany

Private Collection <Department> dept = new ArrayList<Department>();

Now create getter and setter methods for class member variable. We can place this annotation before the getter method of this variable.

public void getDept(){ return dept; } public void setDept(Collection <Department> dept){ this.dept = dept; }

Now Once OneToMany configuration is done in the entity class, create the OneToManyMapping class that create session for these two entity class and insert a row into these tables in the database after creating OneToMany relationship between these tables.

In OneToManyMapping class, two objects emp and dept of Employee and Department classes are created respectively. Call setter methods to insert data into tables using these objects as follows:

Employee emp = new Employee(); Department dept1 = new Department(); Department dept2 = new Department(); emp.setEmpId(“1”); emp.setEmpName(“Emp1”); dept1.setDeptId(“1”); dept1.setDeptName(“Dept1”); dept2.setDeptId(“2”); dept2.setDeptName(“Dept2”);

Now add department type object to employee type department getter method as collection element, which is as follows:

emp.getDept().add(dept1); emp.getDept().add(dept2);

Now, Save these three objects into the session objects and commit the transaction.

This will produce result, once we run OneToManyMapping class as shown below in the figure:

Figure 2: Hibernate Creates OneToMany Relationship, where it creates a new relationship table

This time, hibernate creates a new table showing the relationship between two tables named Employee and Department. This new table has two attributes according to Employee and Department id column.

We can modify the relationship table name and its attribute name as user defined instead of as default attribute name according to class member variable name. This can be done using annotation @JoinTable with its attribute like name with desired table name and joinColumns for table column names as listed below:

@JoinTable (name = “relationalTable” , joinColumns = @JoinColumn(name = “empId”),inverseJoinColumns=@JoinColumn(name = “deptId”))

After adding above instruction after @OneToMany line instruction, the database schema will be updated as shown in following figure:

Figure 3: Relational Table is updated to relationalTable name given by @JoinTable annotation

The inverseJoinColumn is representing the other column attribute of the table.

Many to One Mapping: Whereas multiple attributes of a table having relationship with a single attribute of another table is referred as Many to One mapping. Ex.: Multiple departments may related with a single employee.

Figure 4: Many to One Mapping

ManyToOne Mapping, use annotation @ManyToOne before Employee object declaration or its getter method, in Department table. This kind of relationship will defines multiple department access to a single employee.

Now we are using both of the mappings onto these two tables (Employee and Department), that will represent the bi – directional mapping.

Figure 5: Bi – Directional Mapping

Declare Employee object into the Department class and define annotation @ManyToOne to declare Many To One relationship for Employee with Department table. This annotation is defined in javax.persistance.ManyToOne class.

@ManyToOne private Employee emp;

Now declare getter and setter methods for this class type variable.

public Employee getEmp(){ return emp; } public void setEmp(Employee emp){ this.emp = emp; }

The setter method setEmp() will be called into the OneToManyMapping class to define bi-directional mapping as follows:

dept1.setEmp(emp); dept2.setEmp(emp);

In this way, a single employee is assigned to multiple department as shown in following figure:

Figure 6: emp_empId is added with department table using many to one relationship.

Example Coding:

Listing 1: Employee.java (Employee entity class to create employee database table)

import java.util.ArrayList; import java.util.Collection; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.OneToMany; @Entity public class Employee { @Id private int empId; private String empName; @OneToMany @JoinTable (name = "relationalTable" , joinColumns = @JoinColumn(name = "empId"),inverseJoinColumns=@JoinColumn(name = "deptId")) private Collection <Department> dept = new ArrayList<Department>(); public int getEmpId() { return empId; } public void setEmpId(int empId) { this.empId = empId; } public Collection<Department> getDept() { return dept; } public void setDept(Collection<Department> dept) { this.dept = dept; } @Column public String getEmpName() { return empName; } public void setEmpName(String empName) { this.empName = empName; } }

Listing 2: Department.java (Department entity class to create employee database table)

import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.ManyToOne; @Entity public class Department { int deptId; String deptName; private Employee emp; @ManyToOne public Employee getEmp() { return emp; } public void setEmp(Employee emp) { this.emp = emp; } @Id public int getDeptId() { return deptId; } public void setDeptId(int deptId) { this.deptId = deptId; } @Column public String getDeptName() { return deptName; } public void setDeptName(String deptName) { this.deptName = deptName; } }

Listing 3: OneToManyMapping.java (OneToManyMapping Class to run hibernate configuration to create Many To One and One To Many Mapping)

import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class OneToManyMapping { public static void main(String[]args){ Configuration cfg = new Configuration(); cfg.configure("hibernate.cfg.xml"); SessionFactory sessionFactory = cfg.buildSessionFactory(); Session session = sessionFactory.openSession(); Employee emp = new Employee(); Department dept1 = new Department(); Department dept2 = new Department(); emp.setEmpId(2); emp.setEmpName("Emp1"); dept1.setDeptId(1); dept1.setDeptName("Dept1"); dept2.setDeptId(2); dept2.setDeptName("Dept2"); emp.getDept().add(dept1); emp.getDept().add(dept2); session.beginTransaction(); session.save(emp); session.save(dept1); session.save(dept2); session.getTransaction().commit(); session.close(); } }

Listing 4: hibernate.cfg.xml (Hibernate Configuration file)

<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <!-- Generated by MyEclipse Hibernate Tools. --> <hibernate-configuration> <session-factory> <!-- Database Connection Settings --> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost/test</property> <property name="connection.username">root</property> <property name="connection.password"></property> <!-- JDBC Connection Pool (Use the built-IN) --> <property name="connection.pool_size">1</property> <!-- Diable the second-level cache --> <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property> <!-- Database Schema Modification Type --> <property name="hbm2ddl.auto">create</property> <!-- Database Dialect --> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <!-- Echo all executed SQL to stdout --> <property name="show_sql">true</property> <!-- Hibernate Class Mapping --> <mapping class = "mapping.Employee"/> <mapping class = "mapping.Department"/> </session-factory> </hibernate-configuration>

Directory Structure:

Figure 7: Hibernate Directory structure for OneToOne Mapping Example

Required Jar Files:

Figure 8: Required jar files to run this example

Tools Used:

Eclipse Juno

MySql Database

JDK1.6

Conclusion:

In this article, we learn: