Hibernate Many To Many Annotation Example
Many-To-Many are a relationship between source and target object where source object is an attribute which stores collection of target objects. If target objects are an inverse relationship back to source object then this is called Many-To-Many relationship. In relational database source and target object relationship is defined using foreign key and query in both direction is always exists. But in JPA and Java it is just opposite, relationship are unidirectional means if source object references to target object then it is no guarantee that target object will also have relationship to source object.
In Java Persistent API (JPA) Many-To-Many relationship has been defined using @ManyToMany annotation or element.
All Many-To-Many relationships needs JoinTable. JoinTable can be defined through @JoinTable JPA annotation and also using XML element. JoinTable defines foreign key to source object primary key joinColumns where foreign key of the target objects primary key inverseJoinColumns. Generally primary key of JoinTable is combination of both foreign keys.
Note: This tutorial is an extension of Hibernate Many To Many tutorial so please do all environment related setup using this tutorial. Please follow below steps:
Step 1: Create table in database using below script where we are using two table Employee and Project and joining both table relationship using third table Employee_Project. Employee can work on many project and project can have many employees (Many-To-Many) relationship between Employee and Project.
CREATE TABLE Employee ( First_Name varchar(50) NULL, Last_Name varchar(50) NULL, Employee_Id int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (Employee_Id) ) GO CREATE TABLE Project ( Project_Name varchar(50) NULL, Project_Id int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (Project_Id) ) GO CREATE TABLE Employee_Project ( Employee_Id int(11) NOT NULL, Project_Id int(11) NOT NULL, PRIMARY KEY (Employee_Id,Project_Id), CONSTRAINT FK_Employee FOREIGN KEY (Employee_Id) REFERENCES Employee (Employee_Id), CONSTRAINT FK_Project FOREIGN KEY (Project_Id) REFERENCES Project (Project_Id) ) GO
Step 2: After you created table in database please generate domain code *.java, *.cfg.xml file by using this hibernate tutorial to generate all related files
Step 3: Final project structure:
Step 4: pom.xml file:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.javahonk</groupId> <artifactId>HibernateManyToManyAnnotation</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>HibernateManyToManyAnnotation Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <!-- MySQL database --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.9</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-annotations</artifactId> <version>3.5.6-Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate</artifactId> <version>3.2.3.ga</version> </dependency> <dependency> <groupId>dom4j</groupId> <artifactId>dom4j</artifactId> <version>1.6.1</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> <version>3.2.1</version> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>2.2</version> </dependency> <dependency> <groupId>javax.transaction</groupId> <artifactId>jta</artifactId> <version>1.1</version> </dependency> <dependency> <groupId>asm</groupId> <artifactId>asm</artifactId> <version>3.1</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.5.0</version> </dependency> <dependency> <groupId>javassist</groupId> <artifactId>javassist</artifactId> <version>3.12.1.GA</version> </dependency> </dependencies> <build> <finalName>HibernateManyToManyAnnotation</finalName> </build> </project>
Step 5: HibernateUtil.java inside com.javahonk.util package:
package com.javahonk.util; import org.hibernate.SessionFactory; import org.hibernate.cfg.AnnotationConfiguration; public class HibernateUtil { private static final SessionFactory sessionFactory = buildSessionFactory(); private static SessionFactory buildSessionFactory() { try { return new AnnotationConfiguration().configure() .buildSessionFactory(); } catch (Throwable ex) { System.err.println("Initial SessionFactory" + " creation failed." + ex); throw new ExceptionInInitializerError(ex); } } public static SessionFactory getSessionFactory() { return sessionFactory; } public static void shutdown() { getSessionFactory().close(); } }
Step 6: hibernate.cfg.xml inside src/main/resource folder and don’t forget to replace your database configuration:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory name="sessionFactory"> <property name="hibernate.bytecode.use_reflection_optimizer">false</property> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.password">admin</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/JavaHonk</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.search.autoregister_listeners">false</property> <mapping class="com.javahonk.bean.Project" /> <mapping class="com.javahonk.bean.Employee" /> </session-factory> </hibernate-configuration>
Step 7: Employee.java inside com.javahonk.bean package:
package com.javahonk.bean; // Generated May 22, 2014 10:03:19 PM by Hibernate Tools 4.0.0 import java.util.HashSet; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import static javax.persistence.GenerationType.IDENTITY; import javax.persistence.Id; import javax.persistence.Table; /** * Employee generated by hbm2java */ @Entity @Table(name = "employee", catalog = "JavaHonk") public class Employee implements java.io.Serializable { private Integer employeeId; private String firstName; private String lastName; private Set<Project> projects = new HashSet<Project>(); public Employee() { } public Employee(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } @Id @GeneratedValue(strategy = IDENTITY) @Column(name = "Employee_Id", unique = true, nullable = false) public Integer getEmployeeId() { return this.employeeId; } public void setEmployeeId(Integer employeeId) { this.employeeId = employeeId; } @Column(name = "First_Name", length = 50) public String getFirstName() { return this.firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } @Column(name = "Last_Name", length = 50) public String getLastName() { return this.lastName; } public void setLastName(String lastName) { this.lastName = lastName; } @ManyToMany(cascade = {CascadeType.ALL}) @JoinTable(name="Employee_Project", joinColumns={@JoinColumn(name="Employee_Id")}, inverseJoinColumns={@JoinColumn(name="Project_Id")}) public Set<Project> getProjects() { return projects; } public void setProjects(Set<Project> projects) { this.projects = projects; } }
Step 8: Project.java inside com.javahonk.bean package:
package com.javahonk.bean; // Generated May 22, 2014 10:03:19 PM by Hibernate Tools 4.0.0 import java.util.HashSet; import java.util.Set; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.ManyToMany; import static javax.persistence.GenerationType.IDENTITY; import javax.persistence.Id; import javax.persistence.Table; /** * Project generated by hbm2java */ @Entity @Table(name = "project", catalog = "JavaHonk") public class Project implements java.io.Serializable { private Integer projectId; private String projectName; private Set<Employee> employees = new HashSet<Employee>(); public Project() { } public Project(String projectName) { this.projectName = projectName; } @Id @GeneratedValue(strategy = IDENTITY) @Column(name = "Project_Id", unique = true, nullable = false) public Integer getProjectId() { return this.projectId; } public void setProjectId(Integer projectId) { this.projectId = projectId; } @Column(name = "Project_Name", length = 50) public String getProjectName() { return this.projectName; } public void setProjectName(String projectName) { this.projectName = projectName; } @ManyToMany(mappedBy="projects") public Set<Employee> getEmployees() { return employees; } public void setEmployees(Set<Employee> employees) { this.employees = employees; } }
Step 9: Main test class: ManyToManyTest.java inside com.javahonk package
package com.javahonk; import java.util.List; import java.util.Set; import org.hibernate.Session; import org.hibernate.SessionFactory; import com.javahonk.bean.Employee; import com.javahonk.bean.Project; import com.javahonk.util.HibernateUtil; public class ManyToManyTest { static SessionFactory sf = HibernateUtil.getSessionFactory(); public static void main(String[] args) { insertData(); selectInsertedData(); } private static void selectInsertedData() { Session session = sf.openSession(); session.beginTransaction(); List<Employee> emList = session.createQuery("from Employee") .list(); for (Employee employee : emList) { System.out.println("Employee table data:"); System.out.println("First Name: "+employee.getFirstName() +" Last Name: "+employee.getLastName()+"\n"); System.out.println("Project table data:"); Set<Project> childs=employee.getProjects(); for (Project project : childs) { System.out.println("Project Name: " +project.getProjectName()+" Project Id: " +project.getProjectId()+"\n"); } } session.getTransaction().commit(); session.close(); } private static void insertData() { Session session = sf.openSession(); session.beginTransaction(); Employee employee = new Employee("Java","Honk"); Employee employee2 = new Employee("Java2","Honk2"); Project project = new Project("Trading System"); Project project2 = new Project("Institutioanl Trading System"); employee.getProjects().add(project); employee.getProjects().add(project2); employee2.getProjects().add(project); employee2.getProjects().add(project2); session.save(employee); session.save(employee2); session.getTransaction().commit(); session.close(); } }
Step 10: Let’s run it: — Right click OneToManyInsert.java –> Run As –> Java Application. You will see data inserted and retrieved from table that shows on console below:
Step 11: Below example data inserted to the table:
Download project: HibernateManyToManyAnnotation
That’s it Hibernate Many To Many Annotation Example . For more information read this hibernate tutorial.
Hi,
I did this in the same way, but deleting a dataset make troubles, since cascade = {CascadeType.ALL}) makes a problem.
Do you have a solution to implement delete an employee?
best regards
Didi