Hibernate One To One Mapping using Annotation

In this tutorial I will show how to do One to One mapping using Hibernate Annotation. Figure 4.1 illustrates one-to-one relationship, via Hibernate Annotation.

Figure 4.1 Figure 4.1

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

Figure 4.2 Relational Database (one to one relationship)
Figure 4.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;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;


@Entity
@Table(name = "EMPLOYEE")
public class Employee {
	@Id
	@GeneratedValue(strategy= GenerationType.AUTO)
	@Column(name = "EMPLOYEE_ID")
	private int employeeId;
	
	@Column(name = "Name")
	private String name;
	
	@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "employee")
	@JoinColumn(name="employee_id")
	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;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;

@Entity
@Table(name = "EmployeeDetails")
public class EmployeeDetail {
	
	@Id
	@GeneratedValue(generator="foreign")
    @GenericGenerator(name="foreign", strategy = "foreign", parameters={
      @Parameter(name="property", value="employee")
    })
	@Column(name = "EMPLOYEE_ID")
	private int employeeId;
	
	@Column(name = "City")
	private String city;
	
	@Column(name = "Province")
	private String province;
	
	@Column(name = "Country")
	private String country;
	
	@OneToOne(fetch = FetchType.LAZY, optional=true)
    @PrimaryKeyJoinColumn
    @Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE})
	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;
	}
}

We use the @OneToOne Annotation to create the one-to-one relationship between the Employee and EmployeeDetails entities.

3. 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 class="com.kruders.model.bean.Employee" />
	<mapping class="com.kruders.model.bean.EmployeeDetail" />
</session-factory>
</hibernate-configuration>

4. 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.AnnotationConfiguration;
  
public class HibernateUtil {
  
    private static final SessionFactory sessionFactory = buildSessionFactory();
  
    private static SessionFactory buildSessionFactory() {
        try {
            // Create the SessionFactory from hibernate.cfg.xml
            return new AnnotationConfiguration().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;
    }
}

5. 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("LA", "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(5);
	}
	
	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();
		}
	}
}

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

Figure 4.3 Figure 4.3

You can download the source code of this example here.

2 Responses to Hibernate One To One Mapping using Annotation