Hibernate Many-To-Many Mapping Using Java Annotations Tutorial with Examples

Many To Many Relationship

A Many To Many relationship in Java is where the source object has an attribute that stores a collection of target objects and (if) those target objects had the inverse relationship back to the source object it would also be a ManyToMany relationship.

All ManyToMany relationships require a JoinTable. The JoinTable is defined using the @JoinTable annotation and XML element. The JoinTable defines a foreign key to the source object’s primary key (joinColumns), and a foreign key to the target object’s primary key (inverseJoinColumns). Normally the primary key of the JoinTable is the combination of both foreign keys.

Creating Database

Before we start lets create a simple database and table to apply hibernate operations on. Copy and Paste the following sql query in your query editor and execute.
CREATE table STUDENT (student_id int identity NOT NULL PRIMARY KEY,
rollno varchar(20),
firstname varchar(50),
lastname varchar(50),
course varchar(50))

CREATE TABLE STUDENT_MARKS_DETAILS (student_id int NOT NULL  FOREIGN KEY REFERENCES STUDENT (student_id),
test_id int NOT NULL identity PRIMARY KEY, 
subject varchar(100) DEFAULT NULL, 
max_marks varchar(100) DEFAULT NULL, 
marks_obtained varchar(100) DEFAULT NULL,
result varchar(100) DEFAULT NULL 
)

CREATE TABLE STUDENT_TEST (   
student_id int NOT NULL FOREIGN KEY REFERENCES STUDENT (student_id),  
test_id int NOT NULL FOREIGN KEY REFERENCES STUDENT_MARKS_DETAILS (test_id),
PRIMARY KEY (student_id,test_id),   
) 

NOTE : Above script is written for SQL Server, you can change accordingly for different DB.

Adding Hibernate Jars

Download latest Hibernate jars from here http://hibernate.org/ and add to your classpath. Create Model Classes As a next step let’s create the model classes Student.java and StudentMarksDetails.java using Annotations. The contents of the model classes are as below

Student.java

package com.tutorialsdesk.hibernate.bean;

import java.io.Serializable;
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.GenerationType;
import javax.persistence.Id; 
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;    
import javax.persistence.UniqueConstraint;
import javax.persistence.JoinColumn;
@Entity 
@Table(name="STUDENT",uniqueConstraints = { @UniqueConstraint(columnNames = "student_id") }) 

public class Student implements Serializable {

 private static final long serialVersionUID = 5502738307095121008L;

 @Id   
 @GeneratedValue(strategy = GenerationType.AUTO)
 @Column(name = "student_id")  
 private int id;
 
 @Column(name="rollno")   
 private String rollno;
 
 @Column(name="firstname")   
 private String firstname;
 
 @Column(name="lastname")     
 private String lastname;
 
 @Column(name="course")   
 private String course;
    
  // @OneToOne(cascade = CascadeType.ALL)  
 //@PrimaryKeyJoinColumn 
 //private StudentAddress address;
    
 @ManyToMany(cascade = { CascadeType.ALL })   
 @JoinTable(name = "STUDENT_TEST", joinColumns = {
   @JoinColumn(name = "STUDENT_ID") },
   inverseJoinColumns = { @JoinColumn(name = "TEST_ID") })   
 private Set<StudentMarksDetails> studentMarksDetails = new HashSet<StudentMarksDetails>();   

    
    public Student(){
     
    }
    
 public Student(String rollno, String firstname, String lastname,
   String course) {
  super();
  this.rollno = rollno;
  this.firstname = firstname;
  this.lastname = lastname;
  this.course = course;
  //this.address = address;
 }
 @Override  
 public boolean equals(Object emp) {   
   if (emp instanceof Student) {   
    Student student = (Student) emp;   
   
    if (this.firstname.equals(student.getFirstname())   
      && this.lastname.equals(student.getLastname())   
      && this.rollno.equals(student.getRollno())   
      && this.course.equals(student.getCourse()))   
     return true;   
   }   
   
   return false;   
  }   

 @Override  
 public int hashCode() {   
  
 return this.firstname.hashCode() + this.lastname.hashCode()   
  + this.rollno.hashCode() + this.course.hashCode();   
  }   


 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id;
 }

 public String getRollno() {
  return rollno;
 }

 public void setRollno(String rollno) {
  this.rollno = rollno;
 }

 public String getFirstname() {
  return firstname;
 }

 public void setFirstname(String firstname) {
  this.firstname = firstname;
 }

 public String getLastname() {
  return lastname;
 }

 public void setLastname(String lastname) {
  this.lastname = lastname;
 }

 public String getCourse() {
  return course;
 }

 public void setCourse(String course) {
  this.course = course;
 }

 /*public StudentAddress getAddress() {
  return address;
 }

 public void setAddress(StudentAddress address) {
  this.address = address;
 }
*/
 public Set<StudentMarksDetails> getMarksDetails() {
  return studentMarksDetails;
 }

 public void setMarksDetails(Set<StudentMarksDetails> marksDetails) {
  this.studentMarksDetails = marksDetails;
 }


 
}


StudentMarksDetails.java

package com.tutorialsdesk.hibernate.bean;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

@Entity
@Table(name = "STUDENT_MARKS_DETAILS")
public class StudentMarksDetails {

 @Id
 @GeneratedValue
 @Column(name = "test_id")
 private long testId;

 @Column(name = "subject")
 private String subject;

 @Column(name = "max_marks")
 private String maxMarks;

 @Column(name = "marks_obtained")
 private String marksObtained;

 @Column(name = "result")
 private String result;
 
 @ManyToMany(mappedBy = "studentMarksDetails")   
private Set<Student> student = new HashSet<Student>();  
 
 
 public StudentMarksDetails() {
 }

 public StudentMarksDetails(String subject, String maxMarks, String marksObtained,
   String result) {
  this.subject = subject;
  this.maxMarks = maxMarks;
  this.marksObtained = marksObtained;
  this.result = result;
 }

 public long getTestId() {
  return testId;
 }

 public void setTestId(long testId) {
  this.testId = testId;
 }

 public String getSubject() {
  return subject;
 }

 public void setSubject(String subject) {
  this.subject = subject;
 }

 public String getMaxMarks() {
  return maxMarks;
 }

 public void setMaxMarks(String maxMarks) {
  this.maxMarks = maxMarks;
 }

 public String getMarksObtained() {
  return marksObtained;
 }

 public void setMarksObtained(String marksObtained) {
  this.marksObtained = marksObtained;
 }

 public String getResult() {
  return result;
 }

 public void setResult(String result) {
  this.result = result;
 }

 public Set<Student> getStudent() {   
  return student;   
}   

 public void setStudent(Set<Student> student) {   
  this.student = student;   
 }   


}

Adding Hibernate Configuration file

The hibernate.cfg.xml is as follows:
<?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">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">net.sourceforge.jtds.jdbc.Driver</property>
        <property name="hibernate.connection.password">password</property>
        <property name="hibernate.connection.url">jdbc:jtds:sqlserver://localhost:1433/SBMUATDB</property>
        <property name="hibernate.connection.username">username</property>
        <property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>
     <property name="connection.pool_size">1</property>
        <property name="hbm2ddl.auto">create</property>
        <property name="show_sql">true</property>  
  <property name="format_sql">true</property>  
        <mapping class="com.tutorialsdesk.hibernate.bean.Student"/>
        <mapping class="com.tutorialsdesk.hibernate.bean.StudentMarksDetails"/>
       <!--  <mapping class="com.tutorialsdesk.hibernate.bean.StudentAddress"/>  -->
    </session-factory>
</hibernate-configuration>



In the above file we have set the database connection to SQL Server database . The show_sql option, if set to true will display all the executed SQL queries on the console. The property hbm2ddl.auto , if set to create, creates the schema, destroying the previous data.

Note : In case you want to use any other database then, you need to change these properties – “dialect”, “connection.driver_class”, “connection.url”, “connection.username”, and “connection.password”.

Also we have added the Annotation based entity classes Student.java and StudentMarksDetails.java to the above file.

Create Utility class

Next, we will write a utility class to take care of Hibernate start up and retrieve the session easily. We will write the file HibernateUtil.java as below:
package com.tutorialsdesk.hibernate;

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();
  }


}


Main AnnotationTest class

This class tests the Many-to-Many relationship by creating and listing the student details and corresponding addresses as below:
package com.tutorialsdesk.hibernate;

import java.util.ArrayList;

import org.hibernate.*;

import com.tutorialsdesk.hibernate.bean.Student;
import com.tutorialsdesk.hibernate.bean.StudentMarksDetails;

public class AnnotationTest {
public static void main(String[] args) {
 
 SessionFactory sf = HibernateUtil.getSessionFactory();
   Session session = sf.openSession();

   session.beginTransaction();

   Student student1 = new Student("2013HZ58073","Amit","Sharma","B.Tech");
   Student student2 = new Student("2013HZ58075", "Sweta", "Nagpal","MCA");

   StudentMarksDetails test1 = new StudentMarksDetails("Maths", "100", "87", "Passed");
   StudentMarksDetails test2 = new StudentMarksDetails("Science", "100", "90", "Passed");

   student1.getMarksDetails().add(test1);
   student1.getMarksDetails().add(test2);
   student2.getMarksDetails().add(test1);
   student2.getMarksDetails().add(test2);

   session.save(student1);
   session.save(student2);

   session.getTransaction().commit();
   session.close();

 
}
}


Hibernate Many-To-Many Mapping Using Java Annotations Tutorial with Examples
Hope we are able to explain you Hibernate Many-To-Many Mapping Using Java Annotations, if you have any questions or suggestions please write to us using contact us form.(Second Menu from top left).

Please share us on social media if you like the tutorial.