Thursday 23 August 2012

Hibernate Many-To-Many Mapping Using Annotations Tutorial


In this example you will learn how to map many-to-many relationship using Hibernate Annotations. Consider the following relationship between Student and Course entity.

According to the relationship a student can enroll in any number of courses and the course can have any number of students.
To create this relationship you need to have a STUDENT, COURSE and STUDENT_COURSE table. The relational model is shown below.

To create the STUDENT, COURSE and STUDENT_COURSE table you need to create the following Java Class files.
Student class is used to create the STUDENT and STUDENT_COURSE table.
01.package com.vaannila.student;
02. 
03.import java.util.HashSet;
04.import java.util.Set;
05. 
06.import javax.persistence.CascadeType;
07.import javax.persistence.Column;
08.import javax.persistence.Entity;
09.import javax.persistence.GeneratedValue;
10.import javax.persistence.Id;
11.import javax.persistence.JoinColumn;
12.import javax.persistence.JoinTable;
13.import javax.persistence.ManyToMany;
14.import javax.persistence.Table;
15. 
16.@Entity
17.@Table(name = "STUDENT")
18.public class Student {
19. 
20.    private long studentId;
21.    private String studentName;
22.    private Set<Course> courses = new HashSet<Course>(0);
23. 
24.    public Student() {
25.    }
26. 
27.    public Student(String studentName) {
28.        this.studentName = studentName;
29.    }
30. 
31.    public Student(String studentName, Set<Course> courses) {
32.        this.studentName = studentName;
33.        this.courses = courses;
34.    }
35. 
36.    @Id
37.    @GeneratedValue
38.    @Column(name = "STUDENT_ID")
39.    public long getStudentId() {
40.        return this.studentId;
41.    }
42. 
43.    public void setStudentId(long studentId) {
44.        this.studentId = studentId;
45.    }
46. 
47.    @Column(name = "STUDENT_NAME", nullable = false, length = 100)
48.    public String getStudentName() {
49.        return this.studentName;
50.    }
51. 
52.    public void setStudentName(String studentName) {
53.        this.studentName = studentName;
54.    }
55. 
56.    @ManyToMany(cascade = CascadeType.ALL)
57.    @JoinTable(name = "STUDENT_COURSE", joinColumns = { @JoinColumn(name = "STUDENT_ID") }, inverseJoinColumns = { @JoinColumn(name = "COURSE_ID") })
58.    public Set<Course> getCourses() {
59.        return this.courses;
60.    }
61. 
62.    public void setCourses(Set<Course> courses) {
63.        this.courses = courses;
64.    }
65. 
66.}
The @ManyToMany annotation is used to create the many-to-many relationship between the Student and Course entities. The @JoinTable annotation is used to create the STUDENT_COURSE link table and @JoinColumn annotation is used to refer the linking columns in both the tables.
Course class is used to create the COURSE table.
01.package com.vaannila.student;
02. 
03.import javax.persistence.Column;
04.import javax.persistence.Entity;
05.import javax.persistence.GeneratedValue;
06.import javax.persistence.Id;
07.import javax.persistence.Table;
08. 
09.@Entity
10.@Table(name="COURSE")
11.public class Course {
12. 
13.    private long courseId;
14.    private String courseName;
15. 
16.    public Course() {
17.    }
18. 
19.    public Course(String courseName) {
20.        this.courseName = courseName;
21.    }
22. 
23.    @Id
24.    @GeneratedValue
25.    @Column(name="COURSE_ID")
26.    public long getCourseId() {
27.        return this.courseId;
28.    }
29. 
30.    public void setCourseId(long courseId) {
31.        this.courseId = courseId;
32.    }
33. 
34.    @Column(name="COURSE_NAME", nullable=false)
35.    public String getCourseName() {
36.        return this.courseName;
37.    }
38. 
39.    public void setCourseName(String courseName) {
40.        this.courseName = courseName;
41.    }
42. 
43.}
Now create the hibernate configuration file with the Student and Course class mapping.
01.<?xml version="1.0" encoding="UTF-8"?>
02.<!DOCTYPE hibernate-configuration PUBLIC
03.        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
05.<hibernate-configuration>
06.    <session-factory>
07.        <property name="hibernate.connection.driver_class"> org.hsqldb.jdbcDriver</property>
08.        <property name="hibernate.connection.url"> jdbc:hsqldb:hsql://localhost<;/property>
09.        <property name="hibernate.connection.username">sa</property>
10.        <property name="connection.password"></property>
11.        <property name="connection.pool_size">1</property>
12.        <property name="hibernate.dialect"> org.hibernate.dialect.HSQLDialect</property>
13.        <property name="show_sql">true</property>
14.        <property name="hbm2ddl.auto">create-drop</property>
15.        <mapping class="com.vaannila.student.Student" />
16.        <mapping class="com.vaannila.student.Course" />
17.    </session-factory>
18.</hibernate-configuration>
Create the Main class to run the example.
01.package com.vaannila.student;
02. 
03.import java.util.HashSet;
04.import java.util.Set;
05. 
06.import org.hibernate.HibernateException;
07.import org.hibernate.Session;
08.import org.hibernate.Transaction;
09. 
10.import com.vaannila.util.HibernateUtil;
11. 
12.public class Main {
13. 
14.    public static void main(String[] args) {
15. 
16.        Session session = HibernateUtil.getSessionFactory().openSession();
17.        Transaction transaction = null;
18.        try {
19.            transaction = session.beginTransaction();
20. 
21.            Set<Course> courses = new HashSet<Course>();
22.            courses.add(new Course("Maths"));
23.            courses.add(new Course("Computer Science"));
24. 
25.            Student student1 = new Student("Eswar", courses);
26.            Student student2 = new Student("Joe", courses);
27.            session.save(student1);
28.            session.save(student2);
29. 
30.            transaction.commit();
31.        } catch (HibernateException e) {
32.            transaction.rollback();
33.            e.printStackTrace();
34.        } finally {
35.            session.close();
36.        }
37. 
38.    }
39.}
On executing the Main class you will see the following output.
The STUDENT table has two records.

The COURSE table has two records.

The STUDENT_COURSE table has four records to link the student and courses.

Each student has enrolled in the same two courses, this illustrates the many-to-many mapping.
The folder structure of the example is shown below.
 

No comments:

Post a Comment