Friday, August 12, 2011

HIBERNATE - Unidirectional Many-to-Many Association

In the following example, we will be going through the unidirectional 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 lots of 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>
    </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"></property>

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

        <property name="phNo" column="PHNO" type="string"></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;

public class Professor implements Serializable {

    private static final long serialVersionUID = 2286787316913029844L;

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

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

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 createStudentProfessor() {

    Student student1 = new Student();
    Student student2 = new Student();

    student1.setName("Vijay");
    student1.setPhNo("3312241124");
    student1.setAddress("St Louis");

    student2.setName("Lakshmi");
    student2.setPhNo("2211221212");
    student2.setAddress("Indiana");

    Professor professor1 = new Professor();
    Professor professor2 = new Professor();

    professor1.setName("Mike");
    professor1.setPhNo("5551115551");
    professor1.setDob(new Date());

    professor2.setName("Jake");
    professor2.setPhNo("4411221144");
    professor2.setDob(new Date());

    Set<Professor> professors = new HashSet<Professor>();
    professors.add(professor1);
    professors.add(professor2);

    student1.setProfessors(professors);
    student2.setProfessors(professors);

    HibernateTemplate ht = new HibernateTemplate(sessionFactory);

    Session s = ht.getSessionFactory().openSession();
    Transaction tx = s.beginTransaction();

    try {

        s.save(student1);
        s.save(student2);
        tx.commit();
    } catch (Exception e) {
        e.printStackTrace();
        tx.rollback();
    } finally {
        s.close();
    }
}

Retrieve Student with Professor:

public void getStudentProfessor() {

    HibernateTemplate ht = new HibernateTemplate(sessionFactory);
    DetachedCriteria criteria = DetachedCriteria.forClass(Student.class,
            "stud");
    criteria.add(Restrictions.eq("stud.id", 1));

    List<Student> students = ht.findByCriteria(criteria);
    for (Student student : students) {

        System.out.println("STUDENT: " + student.getName() + ":"
                + student.getAddress() + ":" + student.getPhNo());
        for (Professor professor : student.getProfessors()) {
            System.out.println("PROFESSOR: " + professor.getName() + ":"
                    + professor.getPhNo());
        }
    }
}

1 comment:

  1. Found a nice book on Spring & Hibernate. Have a look at this blog...

    http://amritendude.blogspot.in/2014/06/new-book-on-spring-4-and-hibernate-4.html

    ReplyDelete