Hibernate Self Join One to Many using Annotation

In this tutorial I will show you how to implement Self-Join One to Many mapping using Hibernate Annotation.

Figure 10.1 illustrates Self Reference one-to-many relationship.

Figure 10.1 Figure 10.1

According to this relationship each employee can have manager and each manager is an employee.

First create a new Java Project and configure it as Maven Project. For Reference, Click Here

Add the following dependencies in pom.xml

<dependencies>
 
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.8.2</version>
        <scope>test</scope>
    </dependency>
 
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.15</version>
    </dependency>
 
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>3.6.3.Final</version>
    </dependency>
 
    <dependency>
        <groupId>javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.12.1.GA</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.6.6</version>
    </dependency>
</dependencies>

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),
    manager_id int(10) REFERENCES employee (employee_id));

2. Pojo

Now create Employee Class as following.

Employee.java

package com.kruders.model.bean;

import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
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;
	
	@Column(name = "manager_id")
	private Integer managerId;
	
	@OneToMany(mappedBy="manager")
	private Set<Employee> employees;
	
	public Set<Employee> getEmployees() {
		return employees;
	}
	public void setEmployees(Set<Employee> employees) {
		this.employees = employees;
	}
	@ManyToOne(cascade={CascadeType.ALL})
    @JoinColumn(name="manager_id", insertable = false, updatable = false)
	private Employee manager;
	
	
	public Employee getManager() {
		return manager;
	}
	public void setManager(Employee manager) {
		this.manager = manager;
	}
	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;
	}
	public Integer getManagerId() {
		return managerId;
	}
	public void setManagerId(Integer managerId) {
		this.managerId = managerId;
	}
}

manager attribute is mapped with @ManyToOne Annotation and employees attribute is mapped with @OneToMany Annotation as shown above.

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" />
</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.util.HibernateUtil;


public class Main {
	public static void main(String args[]) {
		Session session = HibernateUtil.getSessionFactory().openSession();
	    Transaction transaction = null;
		try {
			
			transaction = session.beginTransaction();
			
	        Employee manager = new Employee("Puneet");
	        
	        Employee employee1 = new Employee("Sahil");
	        Employee employee2 = new Employee("Geet");
	        
	        employee1.setManager(manager);
	        employee2.setManager(manager);
	        session.save(manager);
			session.save(employee1);
			session.save(employee2);
			transaction.commit();
		}catch (HibernateException e) {
			transaction.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
		
		//listEmployee();
		//updateEmployee("Puneet", "Raghav");
		//listEmployee();
		//deleteEmployee(2);
	}
	
	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());
               
            }
            transaction.commit();
        } catch (HibernateException e) {
            transaction.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }
    }
	
	public void updateEmployee(String oldName, String newName) {
		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);
            }
            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<Employee> employees = session.createQuery("from Employee where employeeId ='" + employeeId + "'").list();
            for(Employee employee : employees) {
            	System.out.println("Name " + employee.getName());
            	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 10.2

Figure 10.2 Figure 10.2

You can download the source code of this example here.

One Response to Hibernate Self Join One to Many using Annotation

  1. swetha March 22, 2013 at 5:21 am #

    Hi , I m facing issue in deletion, when i delete employee it is deleting manager also.. can you tell what could be the issue..\

    Thanks in advance.

Leave a Reply