Hibernate One To One Mapping Tutorial

In this tutorial I will show how to do One to One mapping using Hibernate. Figure 1.1 illustrates one-to-one relationship, via XML mapping file (hbm).

Figure 1.1 Figure 1.1

According to the relationship each Employee should have a unique Address. The relational model is shown below in Figure 1.2

Figure 1.2 Relational Database (one to one relationship)
Figure 1.2

1. Sql Script

Use the following Sql Script for creating table.


create table Employee(
    EMPLOYEE_ID int(10) primary key NOT NULL AUTO_INCREMENT,
    Name varchar(50));
 
create table EmployeeDetails(
    EMPLOYEE_ID int(10) primary key NOT NULL AUTO_INCREMENT,
    City varchar(50),
    Country varchar(50),
    Province varchar(50),
    Foreign Key(EMPLOYEE_ID)  References Employee(EMPLOYEE_ID) 
    ON DELETE CASCADE);

2. Pojo

Now create Employee and EmployeeDetail Class as following.

Employee.java


package com.kruders.model.bean;

public class Employee {
	private int employeeId;
	private String name;
	private EmployeeDetail employeeDetail;
	
	public EmployeeDetail getEmployeeDetail() {
		return employeeDetail;
	}
	public void setEmployeeDetail(EmployeeDetail employeeDetail) {
		this.employeeDetail = employeeDetail;
	}
	public Employee() {
	}
	public Employee(String name) {
		this.name = name;
	}

	
	public int getEmployeeId() {
		return employeeId;
	}
	public void setEmployeeId(int employeeId) {
		this.employeeId = employeeId;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}


EmployeeDetails.java

package com.kruders.model.bean;

public class EmployeeDetail {

	private int employeeId;

	private String city;
	private String country;
	private String province;
	private Employee employee;

	public EmployeeDetail() {

	}

	public EmployeeDetail(String city, String province, String country) {
		
		this.city = city;
		this.province = province;
		this.country = country;
	}

	public Employee getEmployee() {
		return employee;
	}

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

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	public String getProvince() {
		return province;
	}

	public void setProvince(String province) {
		this.province = province;
	}

	public String getCountry() {
		return country;
	}

	public void setCountry(String country) {
		this.country = country;
	}

	public int getEmployeeId() {
		return employeeId;
	}

	public void setEmployeeId(int employeeId) {
		this.employeeId = employeeId;
	}
}

To map Employee and EmployeeDetails table you need to create the following hibernate mapping files.

3. Hibernate Mapping File

Employee.hbm.xml is used to map the Employee table.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.kruders.model.bean.Employee" table="EMPLOYEE">
	<meta attribute="class-description">This class contains employee details.</meta>
	<id name="employeeId" type="int" column="EMPLOYEE_ID">
		<generator class="native" />
	</id>
	<property name="name" type="string" length="50" column="NAME" />
	<one-to-one name="employeeDetail" class="com.kruders.model.bean.EmployeeDetail"
            cascade="save-update"></one-to-one>
</class>
</hibernate-mapping>

We use one-to-one element to create one-to-one relationship between the Employee and EmployeeDetails entities.
EmployeeDetails.hbm.xml is used to map the EmployeeDetails table.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.kruders.model.bean.EmployeeDetail" table="EmployeeDetails">
	<meta attribute="class-description">This class contains the employee's details.</meta>
		<id name="employeeId" type="int">
            <column name="EMPLOYEE_ID" />
            <generator class="foreign">
                <param name="property">employee</param>
            </generator>
        </id>
		<property name="city" column="CITY" type="string" length="50" />
		<property name="country" column="COUNTRY" type="string" length="50" />
		<property name="province" column="PROVINCE" type="string" length="50" />
		<one-to-one name="employee" class="com.kruders.model.bean.Employee"
            constrained="true"></one-to-one>
</class>
</hibernate-mapping>

4. Hibernate Configuration File

Now create the hibernate configuration file and add all the mapping files.
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.mysql.jdbc.Driver</property>
	<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property>
	<property name="hibernate.connection.username">root</property>
	<property name="hibernate.connection.password"></property>
	<property name="connection.pool_size">1</property>
	<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
	<property name="show_sql">true</property>
	<mapping resource="com/kruders/model/bean/Employee.hbm.xml"/>
	<mapping resource="com/kruders/model/bean/EmployeeDetail.hbm.xml"/>
</session-factory>
</hibernate-configuration>

5. Hibernate Utility Class

Now create HibernateUtil class. The HibernateUtil class helps in creating the SessionFactory from the Hibernate configuration file. A org.hibernate.SessionFactory is used to obtain org.hibernate.Session instances. A org.hibernate.Session represents a single-threaded unit of work. The org.hibernate.SessionFactory is a thread-safe global object that is instantiated once.

package com.kruders.util;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
  
public class HibernateUtil {
  
    private static final SessionFactory sessionFactory = buildSessionFactory();
  
    private static SessionFactory buildSessionFactory() {
        try {
            // Create the SessionFactory from hibernate.cfg.xml
            return new Configuration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            // Make sure you log the exception, as it might be swallowed
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }
  
    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

6. Run Program

Create Main.java class that perform CRUD operations and run it as Java Application

package com.kruders.core;

import java.util.Iterator;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;

import com.kruders.model.bean.Employee;
import com.kruders.model.bean.EmployeeDetail;
import com.kruders.util.HibernateUtil;


public class Main {
	public static void main(String args[]) {
		Session session = HibernateUtil.getSessionFactory().openSession();
		Transaction transaction = null;
		try {
			
			transaction = session.beginTransaction();
			EmployeeDetail employeeDetail = new EmployeeDetail("LA1", "San Francisco", "U.S.");
	        Employee employee = new Employee("Raghav1");
	        employee.setEmployeeDetail(employeeDetail);
	        employeeDetail.setEmployee(employee);
			session.save(employee);
			transaction.commit();
		}catch (HibernateException e) {
			transaction.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
		
		//updateEmployee("Raghav1", "Raghav", "LA", "Delhi");
		//listEmployee();
		//deleteEmployee(1);
	}
	
	public void listEmployee() {
		Session session = HibernateUtil.getSessionFactory().openSession();
		Transaction transaction = null;
		try {
			
			transaction = session.beginTransaction();
			List employees = session.createQuery("from Employee").list();
			for (Iterator iterator = employees.iterator(); iterator.hasNext();) {
				Employee employee = (Employee) iterator.next();
				System.out.println("Name " + employee.getName());
				System.out.println("City " + employee.getEmployeeDetail().getCity());
			}
			transaction.commit();
		} catch (HibernateException e) {
			transaction.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
	}
	
	public void updateEmployee(String oldName, String newName, String oldCity, String newCity) {
		Session session = HibernateUtil.getSessionFactory().openSession();
		Transaction transaction = null;
		try {
			
			transaction = session.beginTransaction();
			List employees = session.createQuery("from Employee where Name ='" + oldName + "'").list();
			for (Iterator iterator = employees.iterator(); iterator.hasNext();) {
				Employee employee = (Employee) iterator.next();
				employee.setName(newName);
				employee.getEmployeeDetail().setCity(newCity);
			}
			transaction.commit();
		} catch (HibernateException e) {
			transaction.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
	}
	
	public void deleteEmployee(Integer employeeId) {
		Session session = HibernateUtil.getSessionFactory().openSession();
		Transaction transaction = null;
		try {
			
			transaction = session.beginTransaction();
			List employees = session.createQuery("from Employee where employeeId ='" + employeeId + "'").list();
			for (Iterator iterator = employees.iterator(); iterator.hasNext();) {
				Employee employee = (Employee) iterator.next();
				session.delete(employee);
			}
			transaction.commit();
		} catch (HibernateException e) {
			transaction.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
	}
}


Building a SessionFactory


SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();


How did Hiberante know where the configuration file was located and which one to load?


When new Configuration() is called, Hibernate searches for a file name hibernate.properties in the root of the classpath. If it’s not found, all hibernate.* properties are loaded and added to the Configuration object.

The folder structure of the example is shown below in Figure 1.3

Figure 1.3 Figure 1.3

You can download the source code of this example here.

2 Responses to Hibernate One To One Mapping Tutorial