JPA / Hibernate One to Many Unidirectional Mapping Example

In this tutorial, we will learn how to implement step by step one-to-many unidirectional entity mapping using JPA, Hibernate and MySQL database.

Overview

There are two types of one-to-many association - 
  • Unidirectional - In this type of association, only the source entity has a relationship field that refers to the target entity. We can navigate this type of association from one side.
  • Bidirectional - In this type of association, each entity (i.e. source and target) has a relationship field that refers to each other. We can navigate this type of association from both sides.
In this tutorial, we will implement unidirectional entity mapping using @OneToMany JPA annotation.

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

Development Steps

  1. Create a Simple Maven Project
  2. Project Directory Structure
  3. POM Dependencies
  4. Creating the JPA Entities(Persistent classes)
  5. Create Hibernate DAO Classes
  6. Create a Hibernate configuration file - HibernateUtil.java (Java Configuration)
  7. Create the Main class and Run an Application

1. Create a Simple Maven Project

Use How to Create a Simple Maven Project in Eclipse article to create a simple Maven project in Eclipse IDE.

2. Project Directory Structure

Let's create a packaging structure for the above created a simple maven project. Refer below screenshot for your reference.

3. POM Dependencies

We are using MySQL database so add MySQL dependency to pom.xml:
<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>
    <parent>
        <groupId>net.javaguides.hibernate</groupId>
        <artifactId>hibernate-tutorial</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>hibernate-one-to-many-example</artifactId>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.13</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.3.7.Final</version>
        </dependency>
    </dependencies>
    <build>
        <sourceDirectory>src/main/java</sourceDirectory>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

4. Creating the JPA Entities(Persistent classes)

Let's create JPA entities which we map with database tables. The @OneToMany JPA annotation is used to link one-to-many unidirectional entity mapping.

Instructor JPA Entity - Instructor.java

package net.javaguides.hibernate.entity;

import java.util.ArrayList;
import java.util.List;

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.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name = "instructor")
public class Instructor {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    @Column(name = "email")
    private String email;

    @OneToMany(cascade = CascadeType.ALL)
    private List < Course > courses = new ArrayList < Course > ();

    public Instructor() {

    }

    public Instructor(String firstName, String lastName, String email) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public List < Course > getCourses() {
        return courses;
    }

    public void setCourses(List < Course > courses) {
        this.courses = courses;
    }
}

Course JPA Entity - Course.java

package net.javaguides.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;

@Entity
@Table(name = "course")
public class Course {

 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 @Column(name = "id")
 private int id;

 @Column(name = "title")
 private String title;

 public Course() {

 }

 public Course(String title) {
  this.title = title;
 }

 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id;
 }

 public String getTitle() {
  return title;
 }

 public void setTitle(String title) {
  this.title = title;
 }

 @Override
 public String toString() {
  return "Course [id=" + id + ", title=" + title + "]";
 }
}

5. Create Hibernate DAO Classes

InstructorDao.java

Let's create InstructorDao class add following hibernate DAO operations for Instructor entity:
package net.javaguides.hibernate.dao;

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

import net.javaguides.hibernate.entity.Instructor;
import net.javaguides.hibernate.util.HibernateUtil;

public class InstructorDao {
    public void saveInstructor(Instructor instructor) {
        Transaction transaction = null;
        try (Session session = HibernateUtil.getSessionFactory().openSession()) {
            // start a transaction
            transaction = session.beginTransaction();
            // save the student object
            session.save(instructor);
            // commit transaction
            transaction.commit();
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        }
    }

    public void updateInstructor(Instructor instructor) {
        Transaction transaction = null;
        try (Session session = HibernateUtil.getSessionFactory().openSession()) {
            // start a transaction
            transaction = session.beginTransaction();
            // save the student object
            session.update(instructor);
            // commit transaction
            transaction.commit();
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        }
    }

    public void deleteInstructor(int id) {

        Transaction transaction = null;
        try (Session session = HibernateUtil.getSessionFactory().openSession()) {
            // start a transaction
            transaction = session.beginTransaction();

            // Delete a instructor object
            Instructor instructor = session.get(Instructor.class, id);
            if (instructor != null) {
                session.delete(instructor);
                System.out.println("instructor is deleted");
            }

            // commit transaction
            transaction.commit();
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        }
    }

    public Instructor getInstructor(int id) {

        Transaction transaction = null;
        Instructor instructor = null;
        try (Session session = HibernateUtil.getSessionFactory().openSession()) {
            // start a transaction
            transaction = session.beginTransaction();
            // get an instructor object
            instructor = session.get(Instructor.class, id);
            // commit transaction
            transaction.commit();
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        }
        return instructor;
    }
}

CourseDao.java

Let's create CourseDao class add following hibernate DAO operations for Course entity:
package net.javaguides.hibernate.dao;

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

import net.javaguides.hibernate.entity.Course;
import net.javaguides.hibernate.util.HibernateUtil;

public class CourseDao {
    public void saveCourse(Course course) {
        Transaction transaction = null;
        try (Session session = HibernateUtil.getSessionFactory().openSession()) {
            // start a transaction
            transaction = session.beginTransaction();
            // save the student object
            session.save(course);
            // commit transaction
            transaction.commit();
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        }
    }

    public void updateCourse(Course course) {
        Transaction transaction = null;
        try (Session session = HibernateUtil.getSessionFactory().openSession()) {
            // start a transaction
            transaction = session.beginTransaction();
            // save the student object
            session.update(course);
            // commit transaction
            transaction.commit();
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        }
    }

    public void deleteCourse(int id) {

        Transaction transaction = null;
        try (Session session = HibernateUtil.getSessionFactory().openSession()) {
            // start a transaction
            transaction = session.beginTransaction();

            // Delete a course object
            Course course = session.get(Course.class, id);
            if (course != null) {
                session.delete(course);
                System.out.println("course is deleted");
            }

            // commit transaction
            transaction.commit();
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        }
    }

    public Course getCourse(int id) {

        Transaction transaction = null;
        Course course = null;
        try (Session session = HibernateUtil.getSessionFactory().openSession()) {
            // start a transaction
            transaction = session.beginTransaction();
            // get an course object
            course = session.get(Course.class, id);
            // commit transaction
            transaction.commit();
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        }
        return course;
    }
}

6. Hibernate Utility File(Java Configuration)

Create a helper class HibernateUtil to bootstrap hibernate.
Map the Instructor and Course entities using the MetadataSources.addAnnotatedClass() method.
package net.javaguides.hibernate.util;

import java.util.Properties;

import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.service.ServiceRegistry;

import net.javaguides.hibernate.entity.Course;
import net.javaguides.hibernate.entity.Instructor;

/**
 * Java based configuration
 * @author ramesh Fadatare
 *
 */
public class HibernateUtil {
    private static SessionFactory sessionFactory;

    public static SessionFactory getSessionFactory() {
        if (sessionFactory == null) {
            try {
                Configuration configuration = new Configuration();

                // Hibernate settings equivalent to hibernate.cfg.xml's properties
                Properties settings = new Properties();
                settings.put(Environment.DRIVER, "com.mysql.cj.jdbc.Driver");
                settings.put(Environment.URL, "jdbc:mysql://localhost:3306/hibernate_db?useSSL=false");
                settings.put(Environment.USER, "root");
                settings.put(Environment.PASS, "root");
                settings.put(Environment.DIALECT, "org.hibernate.dialect.MySQL5InnoDBDialect");

                settings.put(Environment.SHOW_SQL, "true");

                settings.put(Environment.CURRENT_SESSION_CONTEXT_CLASS, "thread");

                settings.put(Environment.HBM2DDL_AUTO, "create-drop");

                configuration.setProperties(settings);
                configuration.addAnnotatedClass(Instructor.class);
                configuration.addAnnotatedClass(Course.class);

                ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
                    .applySettings(configuration.getProperties()).build();
                System.out.println("Hibernate Java Config serviceRegistry created");
                sessionFactory = configuration.buildSessionFactory(serviceRegistry);
                return sessionFactory;

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return sessionFactory;
    }
}

7. Create the Main class and Run an Application

package net.javaguides.hibernate;

import net.javaguides.hibernate.dao.InstructorDao;
import net.javaguides.hibernate.entity.Course;
import net.javaguides.hibernate.entity.Instructor;

public class ManApp {
    public static void main(String[] args) {

        InstructorDao instructorDao = new InstructorDao();

        Instructor instructor = new Instructor("Ramesh", "Fadatare", "ramesh@javaguides.com");
        instructorDao.saveInstructor(instructor);

        // create some courses
        Course tempCourse1 = new Course("Learn Spring Boot");
        instructor.getCourses().add(tempCourse1);

        Course tempCourse2 = new Course("Learn hibernate");
        instructor.getCourses().add(tempCourse2);

        instructorDao.saveInstructor(instructor);
    }
}

Output

Conclusion


In this tutorial, we successfully built a project from scratch and learned how to map a one-to-one unidirectional database relationship using Hibernate/JPA.
You might also be interested in checking out the following articles on JPA and Hibernate -

Comments

  1. Sir can you provide a 1 to many example from a webmvc. Able to input elements from view and update them in mysql db and also be able to retrieve them from view.

    ReplyDelete
    Replies
    1. model attribute can take one object only and it is bounded to single java entity. I was not able to find a suitable example showing multiple model attributes. I found one eg to add those models together in a separate class. That way I can use 1 model attribute from View. How would separate them in controller to bind them to respective entity..

      Delete

Post a comment