Hibernate many-to-many unidirectional mapping using annotation

Hi all,

We have seen one-to-one unidirectional, bidirectional, one-to-many unidirectional, bidirectional and many-to-one unidirectional, bidirectional mappings in previous posts. Here we talk about many-to-many unidirectional mapping using annotations. So let’s start.

Here we gonna see a many-to-many relationship between “Course” and “Student”, ie., “many courses will have many students, the same student can be enrolled in many courses”.

Course_Student_ER

 

 

 

In the following example, Course is the parent entity and Student is the child entity. Our mapping flows from Course to Student.

Since the relation is unidirectional, the child details can be obtained by fetching parent details, but the reverse is not possible.

Here’s the parent entity class, Course.java

package com.hibernateApp.entity;

import java.io.Serializable;
import java.util.List;
import javax.persistence.*;

@Entity
public class Course implements Serializable {

    private long id;
    private String name;
    private List students;

    @Id
    @GeneratedValue
    public long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinTable(name = "Enrollment", joinColumns = {
        @JoinColumn(name = "Course_Id", insertable = false, updatable = false, nullable = false)}, inverseJoinColumns = {
        @JoinColumn(name = "Student_Id", insertable = false, nullable = false, updatable = false)})
    public List getStudents() {
        return students;
    }

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

    public void setName(String name) {
        this.name = name;
    }

    public void setStudents(List students) {
        this.students = students;
    }
}

In the above class, we have created a join table namely “Enrollment”, which maps courses to students.

Course_Student

 

 

 

 

 

 

 

Here’s the child entity class, Student.java

package com.hibernateApp.entity;

import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Student implements Serializable {

    private long id;
    private String name;

    @Id
    @GeneratedValue
    public long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

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

    public void setName(String name) {
        this.name = name;
    }
}

The generic dao class, DAO.java

package com.hibernateApp.dao;

import com.hibernateApp.util.HibernateUtil;
import org.hibernate.FlushMode;
import org.hibernate.Session;

public abstract class DAO {

    private static final ThreadLocal THREAD = new ThreadLocal();

    public static Session getSession() {
        Session session = (Session) DAO.THREAD.get();
        if (session == null) {
            session = HibernateUtil.getSessionFactory().openSession();
            DAO.THREAD.set(session);
            getSession().setFlushMode(FlushMode.COMMIT);
        }
        return session;
    }

    protected static void begin() {
        getSession().beginTransaction();
    }

    protected static void commit() {
        getSession().getTransaction().commit();
    }

    protected static void rollback() {
        getSession().getTransaction().rollback();
        getSession().close();
        DAO.THREAD.set(null);
    }

    protected static void flush() {
        getSession().flush();
    }

    protected static void close() {
        getSession().close();
        DAO.THREAD.set(null);
    }
}

The main class, CourseStudent.java. Note that this class extends the above said DAO.java.

package com.hibernateApp.biz;

import com.hibernateApp.dao.DAO;
import com.hibernateApp.entity.Course;
import com.hibernateApp.entity.Student;
import java.util.ArrayList;
import java.util.List;

public class CourseStudent extends DAO {

    public void save1() throws Exception {
        try {
            begin();
            Course course = new Course();
            course.setName("MCA");
            Student student1 = new Student();
            Student student2 = new Student();
            List students = new ArrayList();
            student1.setName("Rahul");
            student2.setName("Sachin");
            students.add(student1);
            students.add(student2);
            course.setStudents(students);
            getSession().save(course);
            commit();
        } catch (Exception e) {
            System.out.println(e.getMessage());
            rollback();
        } finally {
            flush();
            close();
        }
    }

    public void save2() throws Exception {
        try {
            begin();
            Course course = new Course();
            course.setName("MBA");
            List students = getSession().createCriteria(Student.class).list();
            course.setStudents(students);
            getSession().save(course);
            commit();
        } catch (Exception e) {
            System.out.println(e.getMessage());
            rollback();
        } finally {
            flush();
            close();
        }
    }

    public void listCourses() throws Exception {
        try {
            begin();
            List courses = getSession().createCriteria(Course.class).list();
            for (Course course : courses) {
                System.out.println("Course Id: " + course.getId());
                System.out.println("Course Name: " + course.getName());
                for (Student student : course.getStudents()) {
                    System.out.println("Student Id: " + student.getId());
                    System.out.println("Student Name: " + student.getName());
                }
            }
            commit();
        } catch (Exception e) {
            rollback();
            System.out.println(e.getMessage());
        } finally {
            flush();
            close();
        }
    }

    public void deleteOrphan() throws Exception {
        try {
            begin();
            Course course = (Course) getSession().load(Course.class, new Long(1));
            Student student1 = (Student) getSession().load(Student.class, new Long(1));
            Student student2 = (Student) getSession().load(Student.class, new Long(2));
            course.getStudents().remove(student1);
            course.getStudents().remove(student2);
            getSession().delete(course);
            commit();
        } catch (Exception e) {
            rollback();
            System.out.print(e.getMessage());
        } finally {
            flush();
            close();
        }
    }

    public static void main(String[] args) throws Exception {
        new CourseStudent().listCourses();
    }
}

When we execute the save1() method, it outputs

Hibernate: 
    insert 
    into
        Course
        (name) 
    values
        (?)
Hibernate: 
    insert 
    into
        Student
        (name) 
    values
        (?)
Hibernate: 
    insert 
    into
        Student
        (name) 
    values
        (?)
Hibernate: 
    insert 
    into
        Enrollment
        (Course_Id, Student_Id) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        Enrollment
        (Course_Id, Student_Id) 
    values
        (?, ?)

And the data will be stored in our database tables.

o2o_u_save1

 

 

 

 

 

 
When we execute the save2() method, it outputs

Hibernate: 
    select
        this_.id as id2_0_,
        this_.name as name2_0_ 
    from
        Student this_
Hibernate: 
    insert 
    into
        Course
        (name) 
    values
        (?)
Hibernate: 
    insert 
    into
        Enrollment
        (Course_Id, Student_Id) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        Enrollment
        (Course_Id, Student_Id) 
    values
        (?, ?)

And we will have our tables like this.

o2o_u_save2

 

 

 

 

 

 

 
The configuration file, hibernate.cfg.xml

<?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">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
        <property name="hibernate.connection.url">jdbc:sqlserver://localhost:1433;databaseName=TEST</property>
        <property name="hibernate.connection.username">sa</property>
        <property name="hibernate.connection.password">password</property>
        <property name="hibernate.format_sql">true</property>
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.hbm2ddl.auto">update</property>
        <mapping class="com.hibernateApp.entity.Course"/>
        <mapping class="com.hibernateApp.entity.Student"/>
    </session-factory>
</hibernate-configuration>

The output of the listCourses() method looks like this.

Hibernate:
    select
        this_.id as id1_0_,
        this_.name as name1_0_
    from
        Course this_
Course Id: 1
Course Name: MCA
Hibernate:
    select
        students0_.Course_Id as Course1_1_,
        students0_.Student_Id as Student2_1_,
        student1_.id as id2_0_,
        student1_.name as name2_0_
    from
        Enrollment students0_
    left outer join
        Student student1_
            on students0_.Student_Id=student1_.id
    where
        students0_.Course_Id=?
Student Id: 1
Student Name: Rahul
Student Id: 2
Student Name: Sachin
Course Id: 2
Course Name: MBA
Hibernate:
    select
        students0_.Course_Id as Course1_1_,
        students0_.Student_Id as Student2_1_,
        student1_.id as id2_0_,
        student1_.name as name2_0_
    from
        Enrollment students0_
    left outer join
        Student student1_
            on students0_.Student_Id=student1_.id
    where
        students0_.Course_Id=?
Student Id: 1
Student Name: Rahul
Student Id: 2
Student Name: Sachin

Platform

OS: Windows 7 Enterprise SP 1
IDE: Netbeans 7.1.1
Java: 7 Update 51
Hibernate: 3.2.5
Database: Microsoft SQL Server 2012

Thanks.

Published by

Deepesh Darshan K R

I am Me. In all the world, there is no one else exactly like me. Everything that comes out of me is authentically mine, because I alone chose it. I own everything about me: my body, my feelings, my mouth, my voice, all my actions, whether they be to others or myself. I own my fantasies, my dreams, my hopes, my fears. I own my triumphs and successes, all my failures and mistakes. Because I own all of me, I can become intimately acquainted with me. By so doing, I can love me and be friendly with all my parts. I know there are aspects about myself that puzzle me, and other aspects that I do not know -- but as long as I am friendly and loving to myself, I can courageously and hopefully look for solutions to the puzzles and ways to find out more about me. However I look and sound, whatever I say and do, and whatever I think and feel at a given moment in time is authentically me. If later some parts of how I looked, sounded, thought, and felt turn out to be unfitting, I can discard that which is unfitting, keep the rest, and invent something new for that which I discarded. I can see, hear, feel, think, say, and do. I have the tools to survive, to be close to others, to be productive, and to make sense and order out of the world of people and things outside of me. I own me, and therefore, I can engineer me. I am me, and . . . . . . . . . . I am Okay. Haha.. Let it go.. I am a software engineer working in a MNC here at Kochi itself, specialized on J2EE platform, dribbling with frameworks like struts, hibernate etc.

One thought on “Hibernate many-to-many unidirectional mapping using annotation”

Leave a comment