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