Showing posts with label HIBERNATE. Show all posts
Showing posts with label HIBERNATE. Show all posts

Sunday, February 3, 2013

Generating POJOs from Database Scema (Used HSQL)

Ok, Now in a project we have the tables created in a database server. How can i leverage those tables to generate my hibernate pojos or domain objects easily?

    
          a. Install Hibernate Tools.
          b. Go to Hibernate Perspective (Window -> Open Perspective -> Other -> Hibernate)
          c. In the Hibernate Configurations View, Right click -> Add Configuration
          d. Under Main Tab,
                * Select the project where the POJOS need to be generated.
                * Select the database connection as Hibernate Configured Connection.
                * Create the hibernate Configuration file (Properties file is not mandatory) with the following values.
                    <?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 name="TechFes">
                            <property name="hibernate.connection.driver_class">org.hsqldb.jdbcDriver</property>
                            <property name="hibernate.connection.url">jdbc:hsqldb:hsql://localhost:9001/TechFes</property>
                            <property name="hibernate.connection.username">SA</property>
                            <property name="hibernate.dialect">org.hibernate.dialect.HSQLDialect</property>
                        </session-factory>
                    </hibernate-configuration>
          e. Now go to Run icon (the run icon in Hibernate perspective) and click on Hibernate Code Generation Configurations.
          f. Under Main Tab,
                * Select the output directory where the files has to get generated.
                * Select the "Reverse Engineer from JDBC Connection" checkbox.
                            * Provide the package name under which the domain java objects need to be created.
                            * Uncheck "Detect many-to-many" associations. This will help in generating the pojo objects for the tables that are maintained only for many-many association.
          g. Under Exporters Tab,
                * Check the Domain Code, hibernate cfg file and if required annotations, etc.
               
          h. Click on Run and your domain code should have got generated.

Standalone HSQL DB Setup

I have a project and have the schemas available. But I don't have an actual database setup yet. Now run HSQLDB in standalone mode from command line and load the tables and get going :-) What are the steps to do that?

          a. Download latest version of HSQLDB from http://hsqldb.org.

          b. Goto hsql db folder and create a file named server.properties with the following entries.
                  server.database.0=file:hsqldb/TechFes
                server.dbname.0=TechFes
          c. Once the JAVA_HOME and PATH variables are updated with the correct java location,
               execute this command from hsqldb folder where server.properties file is created
                 
                  >java -classpath lib/hsqldb.jar org.hsqldb.server.Server
                 
               NOTE: This command would create a folder hsqldb and create the files for TechFes database under that folder.
             
          d. Now we need to open the database with additional params to the above command.
         
                >java -classpath lib/hsqldb.jar org.hsqldb.server.Server --database.0 file:hsqldb/TechFes --dbname.0 TechFes
               
             NOTE: This would open the database so clients can connect to it.
            
          e. Now we can use the below command to launch the UI for this database and make changes to the schema.
         
                >java -cp lib/hsqldb.jar org.hsqldb.util.DatabaseManagerSwing

Monday, May 21, 2012

Hibernate Connection Release Modes

Hibernate Connection Release Modes:

The different release modes that are supported by Hibernate are as follows:

1. on_close: The Hibernate session obtains a connection when it first needs to perform some JDBC access and maintains that connection until the session is closed.

2. after_transaction: uses ConnectionReleaseMode.AFTER_TRANSACTION. This setting should not be used in JTA environments. Also note that with ConnectionReleaseMode.AFTER_TRANSACTION, if a session is considered to be in auto-commit mode, connections will be released as if the release mode were AFTER_STATEMENT.

3. after_statement: uses ConnectionReleaseMode.AFTER_STATEMENT. Additionally, the configured ConnectionProvider is consulted to see if it supports this setting (supportsAggressiveRelease()). If not, the release mode is reset to ConnectionReleaseMode.AFTER_TRANSACTION. This setting is only safe in environments where we can either re-acquire the same underlying JDBC connection each time you make a call into ConnectionProvider.getConnection() or in auto-commit environments where it does not matter if we re-establish the same connection

Thursday, May 10, 2012

Hibernate Logging

We can use two ways of hibernate configuration for debugging the sql queries generated by hibernate framework.

1. Using log4j.properties

# Hibernate logging options (INFO only shows startup messages)
Log4j.logger.org.hiernate=INFO

Log4j.rootLogger=INFO, console

#The below logger statement is equivalent to hibernate.show_sql=true
log4j.logger.org.hibernate.SQL = DEBUG

# Log JDBC bind parameter runtime arguments.
# The below logger prints the values binded to sql query and the response from the query.
log4j.logger.org.hibernate.type = TRACE

log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=IPDMS[%d{yyyy-MM-dd HH:mm:ss}] %5p (%F:%L) %m%n

2. Hibernate configuration

<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="use_sql_comments">true</property>

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

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

Thursday, August 11, 2011

HIBERNATE - Bi-directional One-to-Many Association

In the following example, we will be going through the bi-directional One-to-Many association using Hibernate. We will be using the Employee and PhoneNumbers table where each Employee will have one or more phone numbers associated with him/her.

Schema Creation:

We will be creating two tables Employee and PhoneNumbers. The PhoneNumbers table has a foreign key reference to the Employee table.

CREATE TABLE EMPLOYEE (
	EMP_ID INTEGER(5) PRIMARY KEY DEFAULT 1,
	EMP_NAME VARCHAR(30) NOT NULL,
	EMP_DOB DATE NOT NULL
);

CREATE TABLE PHONENUMBERS (
	PH_ID INTEGER(5) PRIMARY KEY DEFAULT 1,
	PH_NUMBER VARCHAR(10) NOT NULL,
	EMP_ID INTEGER(5) NOT NULL,
	FOREIGN KEY (EMP_ID) REFERENCES EMPLOYEE (EMP_ID)
);

HBM Files Creation:

Employee.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="Employee" table="EMPLOYEE">
        <id name="empId" column="EMP_ID" type="integer">
            <generator class="increment"></generator>
        </id>

        <property name="empName" column="EMP_NAME" not-null="true"
            type="string"></property>

        <property name="empDOB" column="EMP_DOB" not-null="true"
            type="date"></property>

        <set name="phoneNumbers" table="PHONENUMBERS" cascade="all"
            lazy="false" inverse="true" order-by="PH_ID ASC">
            <key column="EMP_ID" not-null="true"></key>
            <one-to-many class="PhoneNumbers" />
        </set>
    </class>
</hibernate-mapping>

PhoneNumbers.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="PhoneNumbers" table="PHONENUMBERS">
        <id name="phId" column="PH_ID" type="integer">
            <generator class="increment"></generator>
        </id>

        <property name="phoneNo" column="PH_NUMBER" not-null="true"
            type="string"></property>

        <many-to-one name="employee" column="EMP_ID"
            not-null="true" cascade="all" class="Employee" lazy="false"></many-to-one>
    </class>
</hibernate-mapping>

Java Files:

Employee.java:

package org.mybusiness.pojos;

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

public class Employee implements Serializable {

    private static final long serialVersionUID = 4451804446997564426L;

    private int empId;
    private String empName;
    private Date empDOB;

    // Hibernate expects interfaces like Set, Map, List to be the declaration
    // because while doing retrieve operations Hibernate uses its own Set, etc
    // to fill up the contents in this variable
    private Set<PhoneNumbers> phoneNumbers;

    public Employee() {
        phoneNumbers = new LinkedHashSet<PhoneNumbers>();
    }

    public int getEmpId() {
        return empId;
    }

    public void setEmpId(int empId) {
        this.empId = empId;
    }

    public String getEmpName() {
        return empName;
    }

    public void setEmpName(String empName) {
        this.empName = empName;
    }

    public Date getEmpDOB() {
        return empDOB;
    }

    public void setEmpDOB(Date empDOB) {
        this.empDOB = empDOB;
    }

    public Set<PhoneNumbers> getPhoneNumbers() {
        return phoneNumbers;
    }

    public void setPhoneNumbers(Set<PhoneNumbers> phoneNumbers) {
        this.phoneNumbers = phoneNumbers;
    }

    public void addPhoneNumber(PhoneNumbers phoneNumber) {
        this.phoneNumbers.add(phoneNumber);
    }
}

PhoneNumbers.java:

package org.mybusiness.pojos;

import java.io.Serializable;

public class PhoneNumbers implements Serializable {

    private static final long serialVersionUID = -3505306499633395745L;

    private int phId;
    private String phoneNo;

    // Adding Bi-directionality.
    private Employee employee;

    public int getPhId() {
        return phId;
    }

    public void setPhId(int phId) {
        this.phId = phId;
    }

    public String getPhoneNo() {
        return phoneNo;
    }

    public void setPhoneNo(String phoneNo) {
        this.phoneNo = phoneNo;
    }

    public Employee getEmployee() {
        return employee;
    }

    public void setEmployee(Employee employee) {
        this.employee = employee;
    }
}

Functionalities:

Create Employee:

Approach 1:

public void createEmployeeBidirApproach1() {

    HibernateTemplate ht = new HibernateTemplate(sessionFactory);

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

    try {

        // Create an employee
        Employee emp = new Employee();
        emp.setEmpName("Peter");
        emp.setEmpDOB(Calendar.getInstance().getTime());

        // Save the Employee and get the Primary Key
        Integer key = (Integer) s.save(emp);

        PhoneNumbers phNo = new PhoneNumbers();
        phNo.setPhoneNo("8765432190");
        phNo.setEmployee(emp); // Set the foreign key.

        // Save the phone number
        s.save(phNo);

        phNo = new PhoneNumbers();
        phNo.setPhoneNo("9988776655");
        phNo.setEmployee(emp);// Save the phone number

        // Save the phone number
        s.save(phNo);

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

Approach 2:

public void createEmployeeBidirApproach2() {

    HibernateTemplate ht = new HibernateTemplate(sessionFactory);

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

    try {

        Employee emp = new Employee();
        emp.setEmpName("Jake");
        emp.setEmpDOB(Calendar.getInstance().getTime());

        // Save Employee and get the key
        Integer key = (Integer) s.save(emp);

        PhoneNumbers phNo = new PhoneNumbers();
        phNo.setPhoneNo("7865765412");
        phNo.setEmployee(emp);

        emp.addPhoneNumber(phNo);

        phNo = new PhoneNumbers();
        phNo.setPhoneNo("7766776677");
        phNo.setEmployee(emp);

        emp.addPhoneNumber(phNo);

        // Save the employee again with the phone numbers added
        s.save(emp);
        tx.commit();
    } catch (Exception e) {
        e.printStackTrace();
        tx.rollback();
    } finally {
        s.close();
    }
}

Retrieve Employee:

public void getAllEmployees() {

    HibernateTemplate ht = new HibernateTemplate(sessionFactory);

    DetachedCriteria criteria = DetachedCriteria.forClass(Employee.class,
            "emp");
    criteria.add(Restrictions.le("emp.empId", 10));

    // NOTE: LEFT_JOIN eliminates the selection of all phone numbers from
    // the phonenumbers table. This is necessary when we want to filter out
    // the result set from the dependent entity
    DetachedCriteria child = criteria.createCriteria("emp.phoneNumbers",
            "ph", CriteriaSpecification.LEFT_JOIN);
    child.add(Restrictions.ilike("ph.phoneNo", "2", MatchMode.END));
    child.add(Restrictions.le("ph.phId", 10));
    child.addOrder(Order.desc("ph.phId"));

    // NOTE: The result transformer ensures that the result contains only
    // one Employee object with set of phone numbers. If this transformer is
    // not used, then the result set would be repeated by the number of
    // phone numbers present in the set.
    criteria
            .setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);

    List<Employee> employees = ht.findByCriteria(criteria);

    int count = 1;
    for (Employee employee : employees) {
        System.out.println("Employee Index : " + count++);
        System.out.println("----------------------------");
        printEmployee(employee);
    }
}

public void getPhoneNumbersForEmployee() {

    Integer empId = 5;

    HibernateTemplate ht = new HibernateTemplate(sessionFactory);

    DetachedCriteria criteria = DetachedCriteria.forClass(
            PhoneNumbers.class, "ph");
    criteria.createAlias("ph.employee", "emp");

    criteria.add(Restrictions.eq("emp.empId", 5));

    List<PhoneNumbers> phonenumbers = ht.findByCriteria(criteria);

    for (PhoneNumbers phNo : phonenumbers) {
        System.out.println(phNo.getPhId() + ":" + phNo.getPhoneNo() + ":"
                + phNo.getEmployee().getEmpName());
        System.out.println();
    }
}

private void printEmployee(Employee employee) {

    System.out.println("Employee Id : " + employee.getEmpId());
    System.out.println("Employee Name : " + employee.getEmpName());
    System.out.println("Employee DOB : " + employee.getEmpDOB());

    Set<PhoneNumbers> phNos = employee.getPhoneNumbers();
    System.out.println(phNos.getClass());

    if (phNos != null) {
        for (PhoneNumbers phNo : phNos) {
            System.out.println("PhNo : " + phNo.getPhId() + ", "
                    + phNo.getPhoneNo());
        }
    }
    System.out.println("---------------------------"
            + "--------------------------");
}

HIBERNATE - Unidirectional One-to-Many Association

In the following example, we will be going through the Unidirectional One-to-Many association using Hibernate. We will be using the Employee and PhoneNumbers table where each Employee will have one or more phone numbers associated with him/her.

Schema Creation:

We will be creating two tables Employee and PhoneNumbers. The PhoneNumbers table has a foreign key reference to the Employee table.

CREATE TABLE EMPLOYEE (
	EMP_ID INTEGER(5) PRIMARY KEY DEFAULT 1,
	EMP_NAME VARCHAR(30) NOT NULL,
	EMP_DOB DATE NOT NULL
);

CREATE TABLE PHONENUMBERS (
	PH_ID INTEGER(5) PRIMARY KEY DEFAULT 1,
	PH_NUMBER VARCHAR(10) NOT NULL,
	EMP_ID INTEGER(5) NOT NULL,
	FOREIGN KEY (EMP_ID) REFERENCES EMPLOYEE (EMP_ID)
);

HBM Files Creation:

Employee.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="Employee" table="EMPLOYEE">
        <id name="empId" column="EMP_ID" type="integer">
            <generator class="increment"></generator>
        </id>

        <property name="empName" column="EMP_NAME" not-null="true"
            type="string"></property>

        <property name="empDOB" column="EMP_DOB" not-null="true"
            type="date"></property>

        <set name="phoneNumbers" table="PHONENUMBERS" cascade="all"
            lazy="false" inverse="true" order-by="PH_ID ASC">
            <key column="EMP_ID" not-null="true"></key>
            <one-to-many class="PhoneNumbers" />
        </set>
    </class>
</hibernate-mapping>

PhoneNumbers.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="PhoneNumbers" table="PHONENUMBERS">
        <id name="phId" column="PH_ID" type="integer">
            <generator class="increment"></generator>
        </id>

        <property name="phoneNo" column="PH_NUMBER" not-null="true"
            type="string"></property>

        <property name="empId" column="EMP_ID" not-null="true"
            type="integer"></property>
    </class>
</hibernate-mapping>

Java Files:

Employee.java:

package org.mybusiness.pojos;

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

public class Employee implements Serializable {

    private static final long serialVersionUID = 4451804446997564426L;

    private int empId;
    private String empName;
    private Date empDOB;

    // Hibernate expects interfaces like Set, Map, List to be the declaration
    // because while doing retrieve operations Hibernate uses its own Set, etc
    // to fill up the contents in this variable
    private Set<PhoneNumbers> phoneNumbers;

    public Employee() {
        phoneNumbers = new LinkedHashSet<PhoneNumbers>();
    }

    public int getEmpId() {
        return empId;
    }

    public void setEmpId(int empId) {
        this.empId = empId;
    }

    public String getEmpName() {
        return empName;
    }

    public void setEmpName(String empName) {
        this.empName = empName;
    }

    public Date getEmpDOB() {
        return empDOB;
    }

    public void setEmpDOB(Date empDOB) {
        this.empDOB = empDOB;
    }

    public Set<PhoneNumbers> getPhoneNumbers() {
        return phoneNumbers;
    }

    public void setPhoneNumbers(Set<PhoneNumbers> phoneNumbers) {
        this.phoneNumbers = phoneNumbers;
    }

    public void addPhoneNumber(PhoneNumbers phoneNumber) {
        this.phoneNumbers.add(phoneNumber);
    }
}

PhoneNumbers.java:

package org.mybusiness.pojos;

import java.io.Serializable;

public class PhoneNumbers implements Serializable {

    private static final long serialVersionUID = -3505306499633395745L;

    private int phId;
    private String phoneNo;
    private int empId;

    public int getPhId() {
        return phId;
    }

    public void setPhId(int phId) {
        this.phId = phId;
    }

    public String getPhoneNo() {
        return phoneNo;
    }

    public void setPhoneNo(String phoneNo) {
        this.phoneNo = phoneNo;
    }

    public int getEmpId() {
        return empId;
    }

    public void setEmpId(int empId) {
        this.empId = empId;
    }
}

Functionalities:

Create Employee:

Approach 1:

public void createEmployeeApproach1() {

    HibernateTemplate ht = new HibernateTemplate(sessionFactory);

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

    try {

        // Create an employee
        Employee emp = new Employee();
        emp.setEmpName("Vijay");
        emp.setEmpDOB(Calendar.getInstance().getTime());

        // Save the Employee and get the Primary Key
        Integer key = (Integer) s.save(emp);

        PhoneNumbers phNo = new PhoneNumbers();
        phNo.setPhoneNo("3143143142");
        phNo.setEmpId(key); // Set the foreign key.

        // Save the phone number
        s.save(phNo);

        phNo = new PhoneNumbers();
        phNo.setPhoneNo("3221322132");
        phNo.setEmpId(key);// Save the phone number

        // Save the phone number
        s.save(phNo);

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

Approach 2:

public void createEmployeeApproach2() {

    HibernateTemplate ht = new HibernateTemplate(sessionFactory);

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

    try {

        Employee emp = new Employee();
        emp.setEmpName("Steve");
        emp.setEmpDOB(Calendar.getInstance().getTime());

        // Save Employee and get the key
        Integer key = (Integer) s.save(emp);

        PhoneNumbers phNo = new PhoneNumbers();
        phNo.setPhoneNo("1221221221");
        phNo.setEmpId(key);

        emp.addPhoneNumber(phNo);

        phNo = new PhoneNumbers();
        phNo.setPhoneNo("2212212212");
        phNo.setEmpId(key);

        emp.addPhoneNumber(phNo);

        // Save the employee again with the phone numbers added
        s.save(emp);
        tx.commit();
    } catch (Exception e) {
        e.printStackTrace();
        tx.rollback();
    } finally {
        s.close();
    }
}

Retrieve Employee:

public void getAllEmployees() {

    HibernateTemplate ht = new HibernateTemplate(sessionFactory);

    DetachedCriteria criteria = DetachedCriteria.forClass(Employee.class,
            "emp");
    criteria.add(Restrictions.le("emp.empId", 5));

    // NOTE: LEFT_JOIN eliminates the selection of all phone numbers from
    // the phonenumbers table. This is necessary when we want to filter out
    // the result set from the dependent entity
    DetachedCriteria child = criteria.createCriteria("emp.phoneNumbers",
            "ph", CriteriaSpecification.LEFT_JOIN);
    child.add(Restrictions.ilike("ph.phoneNo", "2", MatchMode.END));
    child.add(Restrictions.le("ph.phId", 10));
    child.addOrder(Order.desc("ph.phId"));

    // NOTE: The result transformer ensures that the result contains only
    // one Employee object with set of phone numbers. If this transformer is
    // not used, then the result set would be repeated by the number of
    // phone numbers present in the set.
    criteria
            .setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);

    List<Employee> employees = ht.findByCriteria(criteria);

    int count = 1;
    for (Employee employee : employees) {
        System.out.println("Employee Index : " + count++);
        System.out.println("----------------------------");
        printEmployee(employee);
    }
}

private void printEmployee(Employee employee) {

    System.out.println("Employee Id : " + employee.getEmpId());
    System.out.println("Employee Name : " + employee.getEmpName());
    System.out.println("Employee DOB : " + employee.getEmpDOB());

    Set<PhoneNumbers> phNos = employee.getPhoneNumbers();
    System.out.println(phNos.getClass());
    
    if (phNos != null) {
        for (PhoneNumbers phNo : phNos) {
            System.out.println("PhNo : " + phNo.getPhId() + ", "
                    + phNo.getPhoneNo());
        }
    }
    System.out.println("---------------------------"
            + "--------------------------");
}