Sunday, August 14, 2011

HIBERNATE - Bidirectional Many-to-Many Association

In the following example, we will be going through the bidirectional Many-to-Many association using Hibernate. We will be using the Student and Professor table where a student will have one or more professors. The same professor will have one or more students.

Schema Creation:

Since many-to-many is not allowed on the database level (Normalization), we will change this to add a junction-entity table in the middle. I am using the name of the junction-entity table to have the combination of both the tables.

The entities will be translated as follows:

STUDENT STUDPROF PROFESSOR
ID SIDID
NAME PIDNAME
PHNO
PHNO
ADDRESS
DOB

CREATE TABLE STUDENT (
	ID INTEGER(5) PRIMARY KEY DEFAULT 1,
	NAME VARCHAR(30) NOT NULL,
	ADDRESS VARCHAR(30) NOT NULL,
	PHNO VARCHAR(10) NOT NULL
);

CREATE TABLE PROFESSOR (
	ID INTEGER(5) PRIMARY KEY DEFAULT 1,
	NAME VARCHAR(30) NOT NULL,
	PHNO VARCHAR(30) NOT NULL,
	DOB DATE NOT NULL
);

CREATE TABLE STUDPROF (
	SID INTEGER(5) NOT NULL DEFAULT 1,
	PID INTEGER(5) NOT NULL DEFAULT 1,
	PRIMARY KEY(SID, PID),
	FOREIGN KEY (SID) REFERENCES STUDENT (ID),
	FOREIGN KEY (PID) REFERENCES PROFESSOR (ID)
);

HBM Files Creation:

Professor.hbm.xml:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.mybusiness.pojos">
    <class name="Professor" table="PROFESSOR">
        <id name="id" column="ID" type="integer">
            <generator class="increment"></generator>
        </id>

        <property name="name" column="NAME" type="string"></property>

        <property name="phNo" column="PHNO" type="string"></property>

        <property name="dob" column="DOB" type="date"></property>

        <set name="students" table="STUDPROF" cascade="all" lazy="false">
            <key column="PID"></key>
            <many-to-many column="SID" class="Student"></many-to-many>
        </set>
    </class>
</hibernate-mapping>

Student.hbm.xml:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.mybusiness.pojos">
    <class name="Student" table="STUDENT">
        <id name="id" column="ID">
            <generator class="increment"></generator>
        </id>

        <property name="name" column="NAME" type="string"
            update="false"></property>

        <property name="address" column="ADDRESS" type="string"
            update="false"></property>

        <property name="phNo" column="PHNO" type="string"
            update="false"></property>

        <set name="professors" table="STUDPROF" cascade="all" lazy="false">
            <key column="SID"></key>
            <many-to-many column="PID" class="Professor"></many-to-many>
        </set>
    </class>
</hibernate-mapping>

Java Files:

Professor.java:

package org.mybusiness.pojos;

import java.io.Serializable;
import java.util.Date;
import java.util.Set;

public class Professor implements Serializable {

    private static final long serialVersionUID = 2286787316913029844L;

    private int id;
    private String name;
    private String phNo;
    private Date dob;

    private Set<Student> students;

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public String getPhNo() {
        return phNo;
    }

    public void setPhNo(String phNo) {
        this.phNo = phNo;
    }

    public Date getDob() {
        return dob;
    }

    public void setDob(Date dob) {
        this.dob = dob;
    }

    public Set<Student> getStudents() {
        return students;
    }

    public void setStudents(Set<Student> students) {
        this.students = students;
    }
}

Student.java:


package org.mybusiness.pojos;

import java.util.Set;

public class Student {

    private int id;
    private String name;
    private String address;
    private String phNo;

    private Set<Professor> professors;

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getPhNo() {
        return phNo;
    }

    public void setPhNo(String phNo) {
        this.phNo = phNo;
    }

    public Set<Professor> getProfessors() {
        return professors;
    }

    public void setProfessors(Set<Professor> professors) {
        this.professors = professors;
    }
}

Functionalities:

Create Student and Professor:

public void createProfessorStudent() {

    Professor professor = new Professor();

    professor.setName("Gautham");
    professor.setPhNo("3144143141");
    professor.setDob(new Date());

    Set<Student> students = new HashSet<Student>();

    Student student = new Student();
    student.setId(5);

    students.add(student);

    student = new Student();
    student.setName("Johny");
    student.setAddress("Santa Clara");
    student.setPhNo("3144443141");

    students.add(student);
    professor.setStudents(students);

    HibernateTemplate ht = new HibernateTemplate(sessionFactory);
    Session session = ht.getSessionFactory().openSession();
    Transaction tx = session.beginTransaction();

    try {

        session.saveOrUpdate(professor);
        tx.commit();
    } catch (Exception e) {
        e.printStackTrace();
        tx.rollback();
    } finally {
        session.close();
    }
}

Retrieve Student with Professor:

public void getProfessorStudent() {

    HibernateTemplate ht = new HibernateTemplate(sessionFactory);
    DetachedCriteria criteria = DetachedCriteria.forClass(Professor.class,
            "prof");
    criteria.add(Restrictions.eq("prof.id", 4));

    List<Professor> professors = ht.findByCriteria(criteria);
    for (Professor prof : professors) {

        System.out.println("PROFESSOR: " + prof.getName() + ":"
                + prof.getPhNo() + ":" + prof.getDob());
        for (Student stud : prof.getStudents()) {
            System.out.println("STUDENT: " + stud.getName() + ":"
                    + stud.getPhNo());
        }
    }
}

No comments:

Post a Comment