Hibernate Many to Many Mapping Example(Annotation Based)

By Dhiraj Ray, 03 March,2017  

In this example we will be discussing about Many To Many mapping in hibernate with an example. We will take a look into how we make use of @JoinTable annotation along with mappedBy atribute in hibernate many to many example. We will be creating an example of Student and Course relationship having many to many mapping in between them to illustrate the concepts.

What is Hibernate Many to Many Mapping

Many to many mapping is an association between two entities where one instance of an entity is associated with multiple instances of another entity and vice-versa. A many-to-many relationship always has two sides called an owning side and a non-owning side. The join operation of a table is defined on the owning side.

In case of hibernate, we define a many to many relationship using a third table called join table. This third table contains primary keys of both the associated table. For example if we have a many to many relationship between Student.java and Course.java, then following will be the table structure. Here the table STU_COURSE represents the third table.

hibernate-many-to-many-mapping

Now let us define the sql for this.

CREATE TABLE students(RECORD_ID INT NOT NULL AUTO_INCREMENT, AGE INT, NAME VARCHAR(255), PRIMARY KEY (RECORD_ID)); CREATE TABLE courses(RECORD_ID INT NOT NULL AUTO_INCREMENT, NAME VARCHAR(255), PRIMARY KEY (RECORD_ID)); CREATE TABLE stu_course(STU_ID INT NOT NULL, COURSE_ID INT NOT NULL); ALTER TABLE stu_course ADD CONSTRAINT FK_qbeqhhmej6daf8pwbd0ibaotp FOREIGN KEY (STU_ID) REFERENCES students (RECORD_ID); ALTER TABLE stu_course ADD CONSTRAINT FK_fww2rc1jkfenli8ngjwy382xq FOREIGN KEY (COURSE_ID) REFERENCES courses (RECORD_ID);

Now let us define our entities and discuss about the different annotations used.

Course.java
package com.devglan.model; import java.util.List; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.ManyToMany; import javax.persistence.Table; @Entity @Table(name = "COURSES") public class Course { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "RECORD_ID") private Integer id; @Column(name = "NAME") private String name; @ManyToMany(fetch = FetchType.LAZY, mappedBy = "courses") private List courses; //getters and setters goes here
Student.java
package com.devglan.model; import java.io.Serializable; import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.Table; @Entity @Table(name = "STUDENTS") public class Student implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "RECORD_ID") private Integer id; @Column(name = "NAME") private String name; @Column(name = "AGE") private Integer age; @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinTable(name = "STU_COURSE", joinColumns = { @JoinColumn(name = "STU_ID") }, inverseJoinColumns = { @JoinColumn(name = "COURSE_ID") }) private List courses; //getters and setters goes here

Its obvious that the annotation @ManyToMany is used to define many to many relationship. If we look into @JoinTable, it has the third table name configured as STU_COURSE. The STU_ID and COURSE_ID will contain the primary key of table STUDENTS and COURSES repectively.

mappedBy : Here mappedBy is used to prevent creation of third table from both sides of the entities. If we remove this element, then all together 4 tables will be created, the forth table will be created as courses_students. As we know mappedBy element always owns the relaionship and this is defined when we have unidiretional relationships

Now we will verify the relationship and to that let us define hibernate configuration using hibernate.cfg.xml and Application.java to make entries in the DB

Defining hibernate.cfg.xml

hibernate.cfg.xml
<hibernate-configuration> <session-factory> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost/test</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">root</property> <property name="hibernate.hbm2ddl.auto">update</property> <property name="show_sql">false</property> <mapping class="com.devglan.model.Student"/> <mapping class="com.devglan.model.Course"/> </session-factory> </hibernate-configuration>

Following is the Application.java

Application.java
package com.devglan.model; import java.util.Arrays; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; public class Application { public static void main(String[] args) { createStudent(); } public static SessionFactory getSessionFactory() { Configuration configuration = new Configuration().configure(); StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder() .applySettings(configuration.getProperties()); SessionFactory sessionFactory = configuration .buildSessionFactory(builder.build()); return sessionFactory; } public static void createStudent() { System.out.println("****************Creating Student*************"); Student student = new Student(); student.setName("John"); student.setAge(23); Course course1 = new Course("John"); Course course2 = new Course("Rohan"); student.setCourses(Arrays.asList(course1, course2)); Session session = getSessionFactory().openSession(); session.beginTransaction(); session.save(student); session.save(course1); session.save(course2); session.getTransaction().commit(); session.close(); System.out.println("Student Created Successfully" + student.toString()); } }

Run Application

Run Application.java as a java application and you can see Student and Course entries in the DB. Also, the third table is populted with corresponding entries.

I hope this article served you whatever you were looking for. If you have anything that you want to add or share then please share it below in the comment section.

Download the source

References: Oracle Many to many Docs Many to Many Docs

Suggest more topics in suggestion section or write your own article and share with your colleagues.

Is this page helpful to you? Please give us your feedback below. We would love to hear your thoughts on these articles, it will help us improve further our learning process.

Further Reading: