17 May 2015

One to Many Relationship in Hibernate

One to many relationship in very common in relational database. In this relationship, parent will be in one table and it will have one or more child in another table. In this example, the consideration is an Employee may be allocated in one or many projects so employee records will be in EMPLOYEE table and the project allocation details will be in another table called EMPLOYEE_ALLOCATION.

In my next blog the same example will be extended to implement many-to-many relationship where one more table will be introduced

Required Software

  • JDK 1.7
  • Maven 2.2.x
  • Eclipse for J2EE
  • Hibernate

Steps to write code

In this example HSQLDB jar has been used. So no real database is required to run the stand alone application

  • Create a simple java project with src/main/java, src/main/resources as the source directory. Once project is created, you can add source directory from the below screen (Right click on project -> properties)
  • Convert the project into maven project (Right click on the project -> Configure -> Convert to Maven project)
  • Add the following dependancies in your pom.xml for Hibernate One to Many example

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>HibernateOneToManyExample</groupId>
	<artifactId>HibernateOneToManyExample</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<repositories>
		<repository>
			<id>jboss</id>
			<url>http://repository.jboss.org/maven2</url>
		</repository>
	</repositories>

	<build>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>1.7</source>
					<target>1.7</target>
				</configuration>
			</plugin>
		</plugins>
	</build>

	<dependencies>
		<!-- Hibernate Dependencies -->
		<!-- Hibernate core -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>4.3.6.Final</version>
		</dependency>

		<!-- Hibernate annotation -->
		<dependency>
			<groupId>hibernate-annotations</groupId>
			<artifactId>hibernate-annotations</artifactId>
			<version>3.3.0.GA</version>
		</dependency>

		<dependency>
			<groupId>hibernate-commons-annotations</groupId>
			<artifactId>hibernate-commons-annotations</artifactId>
			<version>3.0.0.GA</version>
		</dependency>

		<!-- Hibernate library dependecy start -->
		<dependency>
			<groupId>dom4j</groupId>
			<artifactId>dom4j</artifactId>
			<version>1.6.1</version>
		</dependency>

		<dependency>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
			<version>1.1.1</version>
		</dependency>

		<dependency>
			<groupId>commons-collections</groupId>
			<artifactId>commons-collections</artifactId>
			<version>3.2.1</version>
		</dependency>

		<dependency>
			<groupId>cglib</groupId>
			<artifactId>cglib</artifactId>
			<version>2.2</version>
		</dependency>
		<!-- Hibernate library dependecy end -->

		<!-- HSQL database -->
		<dependency>
			<groupId>hsqldb</groupId>
			<artifactId>hsqldb</artifactId>
			<version>1.8.0.10</version>
		</dependency>
	</dependencies>
</project>
  • Create other files as shown below

The purpose of each files are described in the below table

SL NO Class Name Description
1 com.ashish.util.HibernateUtil This class will read configuration from hibernate.cfg.xml file and returns SessionFactory
2 com.ashish.entity.EmployeeEntity and com.ashish.entity.EmployeeAllocationEntity These two entity classes are having one to many relationsship. In EmployeeEntity class @OneToMany and in EmployeeAllocationEntity class @ManyToOne annotations are used to established the relationship in hibernate
3 com.ashish.main.MainApp This class contains the main method and creates two employees called Ashish, Ujan and three allocations called Project1, Project2, Project3. Attach Project1 and Project2 with Ashish and Project2 and Project3 with Ujan
  • hibernate.cfg.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.archive.autodetection">class,hbm</property> 
        <property name="hibernate.dialect">org.hibernate.dialect.HSQLDialect</property> 
        <property name="hibernate.show_sql">true</property>   
        <property name="hibernate.connection.driver_class">org.hsqldb.jdbcDriver</property>   
        <property name="hibernate.connection.username">sa</property>   
        <property name="hibernate.connection.password"></property>   
        <property name="hibernate.connection.url">jdbc:hsqldb:mem:ashish</property>   
        <property name="hibernate.hbm2ddl.auto">create</property>   
        <mapping class="com.ashish.entity.EmployeeEntity"></mapping>
        <mapping class="com.ashish.entity.EmployeeAllocationEntity"></mapping>
    </session-factory>
</hibernate-configuration>
  • HibernateUtil.java: This class will read configuration from hibernate.cfg.xml file and returns SessionFactory


package com.ashish.util;

import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
 
public class HibernateUtil
{
   private static SessionFactory sessionFactory = buildSessionFactory();
 
   private static SessionFactory buildSessionFactory()
   {
      try
      {
         if (sessionFactory == null)
         {
            Configuration configuration = new Configuration().configure(HibernateUtil.class.getResource("/hibernate.cfg.xml"));
            StandardServiceRegistryBuilder serviceRegistryBuilder = new StandardServiceRegistryBuilder();
            serviceRegistryBuilder.applySettings(configuration.getProperties());
            ServiceRegistry serviceRegistry = serviceRegistryBuilder.build();
            sessionFactory = configuration.buildSessionFactory(serviceRegistry);
         }
         return sessionFactory;
      } catch (Throwable ex)
      {
         System.err.println("Initial SessionFactory creation failed." + ex);
         throw new ExceptionInInitializerError(ex);
      }
   }
 
   public static SessionFactory getSessionFactory()
   {
      return sessionFactory;
   }
 
   public static void shutdown()
   {
      getSessionFactory().close();
   }
}
  • EmployeeEntity.java: This class has a set to hold the one to many relationship.
@Entity
@org.hibernate.annotations.Entity(dynamicUpdate = true)
@Table(name = "EMPLOYEE", uniqueConstraints = {
		@UniqueConstraint(columnNames = "ID"),
		@UniqueConstraint(columnNames = "EMAIL") })

public class EmployeeEntity implements Serializable {
	private static final long serialVersionUID = -1798070786993154676L;
	@Id
	@Column(name = "ID", unique = true, nullable = false)
	private Integer employeeId;
	@Column(name = "EMAIL", unique = true, nullable = false, length = 100)
	private String email;
	@Column(name = "FIRST_NAME", unique = false, nullable = false, length = 100)
	private String firstName;
	@Column(name = "LAST_NAME", unique = false, nullable = false, length = 100)
	private String lastName;
	@OneToMany(fetch = FetchType.LAZY, mappedBy = "allocationId")
	private Set<EmployeeAllocationEntity> empAllocations = new HashSet<EmployeeAllocationEntity>();

	public EmployeeEntity(int empId, String firstName, String lastName, String emailId) {
		this.employeeId = empId;
		this.firstName = firstName;
		this.lastName = lastName;
		this.email = emailId;
	}
	
	// All getter and setter methods
}
  • EmployeeAllocationEntity.java: @ManyToOne annotation is used to to establish the relationship.

@Entity
@org.hibernate.annotations.Entity(dynamicUpdate = true)
@Table(name = "EMPLOYEE_ALLOCATION", uniqueConstraints = {
		@UniqueConstraint(columnNames = "ID") })
		
public class EmployeeAllocationEntity implements Serializable {
	private static final long serialVersionUID = -1798070786993154676L;
	@Id
	@Column(name = "ID", unique = true, nullable = false)
	private Integer allocationId;
	@Column(name = "ALLOCATION_NAME", unique = true, nullable = false, length = 100)
	private String allocationName;
	@ManyToOne
	@JoinColumn(name="employeeId")
	private EmployeeEntity empEntity;
	
	public EmployeeAllocationEntity(int allocationId, String allocationName, EmployeeEntity emp) {
		this.allocationId = allocationId;
		this.allocationName = allocationName;
		this.empEntity = emp;
	}
	
	// All getter and setter methods
}
  • MainApp.java: This class contains the main method and creates two employees called Ashish, Ujan and three allocations called Project1, Project2, Project3. Attach Project1 and Project2 with Ashish and Project2 and Project3 with Ujan.
package com.ashish.main;

import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.hibernate.Session;
import com.ashish.entity.EmployeeAllocationEntity;
import com.ashish.entity.EmployeeEntity;
import com.ashish.util.HibernateUtil;

public class MainApp
{
   public static void main(String[] args)
   {
      Session session = HibernateUtil.getSessionFactory().openSession();
      session.beginTransaction();
      insertRecord(session);
      selectRecord(session);
      HibernateUtil.shutdown();
   }

	private static void insertRecord(Session session) {
		// Add new Employee object
	      EmployeeEntity emp = new EmployeeEntity(1, "Ashish", "Mondal", "ashismo@gmail.com");
	      
	      // Ashish Mondal has two allocations called Project1 and Project2
	      EmployeeAllocationEntity empAllocation = new EmployeeAllocationEntity(1, "Project1", emp);
	      emp.setEmpAllocations(empAllocation);
	      empAllocation = new EmployeeAllocationEntity(2, "Project2", emp);
	      emp.setEmpAllocations(empAllocation);
	      
	      session.save(emp);
	      
	   // Add another Employee object
	      emp = new EmployeeEntity(2, "Ujan", "Mondal", "ujanmo@gmail.com");
	      
	      // Ujan Mondal has two allocations called Project2 and Project3. 
	      // Also note that: In project 2, Ashish and Ujan both are allocated
	      emp.setEmpAllocations(empAllocation);
	      
	      empAllocation = new EmployeeAllocationEntity(3, "Project3", emp);
	      emp.setEmpAllocations(empAllocation);
	      
	      session.save(emp);
	      
	      // After saving all employees, commit the transaction
	      session.getTransaction().commit();
	}
	
	private static void selectRecord(Session session) {
		// Select Employee
	     List<EmployeeEntity> empList = session.createQuery("from EmployeeEntity").list();
	     for(EmployeeEntity emp : empList) {
	    	 System.out.println("==================Employee Details======================");
	    	 System.out.println("Employee Name: " + emp.getFirstName() + " " + emp.getLastName());
	    	 System.out.println("Email : " + emp.getEmail());
	    	 
	    	 System.out.println("+++++++++++++Employee Allocation Details+++++++++++++");
	    	 Set<EmployeeAllocationEntity> empAllocationSet = emp.getEmpAllocations();
	    	 Iterator<EmployeeAllocationEntity> it = empAllocationSet.iterator();
	    	 while(it.hasNext()) {
	    		 System.out.println("Allocation: " + it.next().getAllocationName());
	    	 }
	     }
	     
	}
}

Output



blog comments powered by Disqus
J2EE,SOAP,RESTful,SVN,PMD,SONAR,JaCoCo,HTTP,API,MAVEN,AngularJS,GitHub,LDAP,AOP,ORM,JMS,MVC,AWS,SQL,PHP,H2DB,JDBC