Hibernate 5 - Many to One association example

Posted on March 26, 2017


Technologies used:   JDK 1.8.0_121 | Hibernate 5.2.6.Final | Maven 3.3.9 | MySQL 5.7.12 | Eclipse Mars.2 (4.5.2)

In this post, we will learn how to map many-to-one relationship between two entities using the Hibernate ORM.

A many-to-one relationship is equivalent to primary key-foreign key relationship in a database.

The @ManyToOne JPA annotation is used to define the many-to-one association between two entities.

Many-To-One relationship example

Consider the following domain model and relational model diagrams of many-to-one association.

many-to-one-domain-model.png

many-to-one.png

According to the above relationship many employees can have the same department.

Jar dependencies

Add the following jar dependencies in pom.xml file.

<dependencies>
  <!-- Mysql Connector -->
  <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>6.0.5</version>
  </dependency>
  <!-- Hibernate 5.2.6 Final -->
  <dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>5.2.6.Final</version>
  </dependency>
</dependencies>

Entity class

Create two @Entity classes - Department and Employee, to map with DEPARTMENT and EMPLOYEE tables respectively.

Department.java

package com.boraji.tutorial.hibernate.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 * @author imssbora
 */
@Entity
@Table(name = "DEPARTMENT")
public class Department {
  
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Column(name = "DPT_ID")
   private long id;

   @Column(name = "NAME", nullable = false, unique = true)
   private String name;

   // Setter and getter methods

}

Employee.java

package com.boraji.tutorial.hibernate.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.ForeignKey;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

/**
 * @author imssbora
 */
@Entity
@Table(name="EMPLOYEE")
public class Employee {
   
   @Id
   @GeneratedValue(strategy=GenerationType.IDENTITY)
   @Column(name="EMP_ID")
   private long id;
   
   @Column(name="NAME",nullable=false)
   private String name;
   
   @Column(name="DESIGNATION")
   private String designation;
   
   @ManyToOne
   @JoinColumn(name="DPT_ID",[email protected](name="DPT_ID_FK"))
   private Department department;

   // Setter and Getter methods
}

A @ManyToOne annotation is typically used with a @JoinColumn annotation to specifies how the relationship should be mapped to the database.

The @JoinColumn defines the name of the foreign key column in the source entity that should be used to find the target entity.

 

Hibernate utility class

Create a helper class HibernateUtil to bootstrap hibernate.

Map the Department and Employee entities using the #MetadataSources.addAnnotatedClass() method.

HibernateUtil.java

package com.boraji.tutorial.hibernate;

import java.util.HashMap;
import java.util.Map;

import org.hibernate.SessionFactory;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;

import com.boraji.tutorial.hibernate.entity.Department;
import com.boraji.tutorial.hibernate.entity.Employee;

public class HibernateUtil {
  private static StandardServiceRegistry registry;
  private static SessionFactory sessionFactory;

  public static SessionFactory getSessionFactory() {
    if (sessionFactory == null) {
      try {
        StandardServiceRegistryBuilder registryBuilder = 
            new StandardServiceRegistryBuilder();

        Map<String, String> settings = new HashMap<>();
        settings.put("hibernate.connection.driver_class", "com.mysql.cj.jdbc.Driver");
        settings.put("hibernate.connection.url", "jdbc:mysql://localhost:3306/BORAJI");
        settings.put("hibernate.connection.username", "root");
        settings.put("hibernate.connection.password", "admin");
        settings.put("hibernate.show_sql", "true");
        settings.put("hibernate.hbm2ddl.auto", "update");

        registryBuilder.applySettings(settings);

        registry = registryBuilder.build();

        MetadataSources sources = new MetadataSources(registry)
            .addAnnotatedClass(Employee.class)
            .addAnnotatedClass(Department.class);

        Metadata metadata = sources.getMetadataBuilder().build();

        sessionFactory = metadata.getSessionFactoryBuilder().build();
      } catch (Exception e) {
        System.out.println("SessionFactory creation failed");
        if (registry != null) {
          StandardServiceRegistryBuilder.destroy(registry);
        }
      }
    }
    return sessionFactory;
  }

  public static void shutdown() {
    if (registry != null) {
      StandardServiceRegistryBuilder.destroy(registry);
    }
  }
}

Main class 

Create the MainApp class to run the application.

MainApp.java

package com.boraji.tutorial.hibernate;

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

import com.boraji.tutorial.hibernate.entity.Department;
import com.boraji.tutorial.hibernate.entity.Employee;

/**
 * @author imssbora
 */
public class MainApp {
  public static void main(String[] args) {
    Session session = null;
    Transaction transaction = null;
    try {
      session = HibernateUtil.getSessionFactory().openSession();
      transaction = session.beginTransaction();
      transaction.begin();

      Department department=new Department();
      department.setName("IT Department");
      
      Employee employee1=new Employee();
      employee1.setName("SCOTT");
      employee1.setDesignation("Developer");
      employee1.setDepartment(department);
      
      Employee employee2=new Employee();
      employee2.setName("ADAMS");
      employee2.setDesignation("Sr. Developer");
      employee2.setDepartment(department);
      
      Employee employee3=new Employee();
      employee3.setName("MILLER");
      employee3.setDesignation("Manager");
      employee3.setDepartment(department);
      
      session.save(department);
      session.save(employee1);
      session.save(employee2);
      session.save(employee3);
      
      transaction.commit();
      
    } catch (Exception e) {
      if (transaction != null) {
        transaction.rollback();
      }
      e.printStackTrace();
    } finally {
      if (session != null) {
        session.close();
      }
    }

    HibernateUtil.shutdown();
  }
}

Output

Hibernate: create table DEPARTMENT (DPT_ID bigint not null auto_increment, NAME varchar(255) not null, primary key (DPT_ID))
Hibernate: create table EMPLOYEE (EMP_ID bigint not null auto_increment, DESIGNATION varchar(255), NAME varchar(255) not null, DPT_ID bigint, primary key (EMP_ID))
Hibernate: alter table DEPARTMENT drop constraint UK_8ry1iwcodl3ily50pgmc89p4e
Hibernate: alter table DEPARTMENT add constraint UK_8ry1iwcodl3ily50pgmc89p4e unique (NAME)
Hibernate: alter table EMPLOYEE add constraint DPT_ID_FK foreign key (DPT_ID) references DEPARTMENT (DPT_ID)
Hibernate: insert into DEPARTMENT (NAME) values (?)
Hibernate: insert into EMPLOYEE (DPT_ID, DESIGNATION, NAME) values (?, ?, ?)
Hibernate: insert into EMPLOYEE (DPT_ID, DESIGNATION, NAME) values (?, ?, ?)
Hibernate: insert into EMPLOYEE (DPT_ID, DESIGNATION, NAME) values (?, ?, ?)

After executing the MainApp class, you will see the following records in DEPARTMENT and EMPLOYEE tables of MySQL database.

mysql> select * from department;
+--------+---------------+
| DPT_ID | NAME          |
+--------+---------------+
|      1 | IT Department |
+--------+---------------+
1 row in set (0.00 sec)

mysql> select * from employee;
+--------+---------------+--------+--------+
| EMP_ID | DESIGNATION   | NAME   | DPT_ID |
+--------+---------------+--------+--------+
|      1 | Developer     | SCOTT  |      1 |
|      2 | Sr. Developer | ADAMS  |      1 |
|      3 | Manager       | MILLER |      1 |
+--------+---------------+--------+--------+
3 rows in set (0.00 sec)

 

Download Sources