14.5 Many to Many mapping
Many to Many mapping requires an additional table (also known as mapping table) which contains the keys of both the tables.
Since this is “many” we will use collections and Hibernate provides <many-to-many> tag to configure this relationship.
Let’s take the simple scenario Employee and Roles. “One employee can have many Roles and one Role can have many employee ” .
Employee.java
package com.tutorial.hibernate; import java.util.HashSet; import java.util.Set; public class Employee { private int id; private String name; private Set<Role> roles= new HashSet<Role>(); public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Set<Role> getRoles() { return roles; } public void setRoles(Set<Role> roles) { this.roles = roles; } }
Role.java
package com.tutorial.hibernate; public class Role { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + id; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Role other = (Role) obj; if (id != other.id) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } @Override public String toString() { return "Role [id=" + id + ", name=" + name + "]"; } }
association-mapping.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="com.tutorial.hibernate.Employee" table="Employee"> <id name="id" type="int" column="person_id"> <generator class="native" /> </id> <property name="name" column="name" type="string" /> <set name="roles" table="role_employee"> <key column="person_id" /> <many-to-many column="role_id" class="com.tutorial.hibernate.Role"> </many-to-many> </set> </class> <class name="com.tutorial.hibernate.Role" table="Role"> <id name="id" type="int" column="role_id"> <generator class="native" /> </id> <property name="name" type="string" column="name" /> </class> </hibernate-mapping>
Create Tables Scripts
CREATE TABLE 'employee' ( 'person_id' int(11) NOT NULL AUTO_INCREMENT, 'name' varchar(255) DEFAULT NULL, PRIMARY KEY ('person_id') ); CREATE TABLE 'role' ( 'role_id' int(11) NOT NULL AUTO_INCREMENT, 'name' varchar(255) DEFAULT NULL, PRIMARY KEY ('role_id') ); CREATE TABLE 'role_employee' ( 'person_id' int(11) NOT NULL, 'role_id' int(11) NOT NULL, PRIMARY KEY ('person_id','role_id'), KEY 'FK_pf0gy1qs5lxxq8tvuoifr2s75' ('role_id'), CONSTRAINT 'FK_tay8ge3bpb764hhjij8eqclum' FOREIGN KEY ('person_id') REFERENCES 'employee' ('person_id'), CONSTRAINT 'FK_pf0gy1qs5lxxq8tvuoifr2s75' FOREIGN KEY ('role_id') REFERENCES 'role' ('role_id') );
Test Program
import java.util.HashSet; import java.util.Set; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import com.tutorial.hibernate.Employee; import com.tutorial.hibernate.Role; public class Test { private static SessionFactory factory; public static void main(String args[]) { Configuration cfg = new Configuration().configure(); factory = cfg.buildSessionFactory(); Session session = factory.openSession(); Transaction tx = session.beginTransaction(); Role role1 = new Role(); role1.setName("Manager"); Role role2 = new Role(); role2.setName("Admin"); Set<Role> roles = new HashSet<Role>(); roles.add(role2); roles.add(role1); Employee employee = new Employee(); employee.setName("Person A"); employee.setRoles(roles); session.save(role1); session.save(role2); int empId = (Integer)session.save(employee); tx.commit(); session.close(); getEmployeeDetails(empId); factory.close(); } private static void getEmployeeDetails(int id) { Session session = factory.openSession(); Employee employee = (Employee)session.get(Employee.class,id); String name= employee.getName(); Set<Role> roles = employee.getRoles(); System.out.println(name); System.out.println(roles); } }
Run Program – Refer below console output and database state
Role Table
Employee Table
Role_Employee Table