Hibernate Tutorial

Core Hibernate

Hibernate Mapping

Hibernate Annotations

Hibernate with Spring Framework

Hibernate with Database

Hibernate Log4j

Inheritance Mapping

Hibernate - One-to-Many Mapping

One-to-many is a common relationship in database modeling where one record in a table can be associated with multiple records in another table. A typical example is a Department having multiple Employee records.

In this tutorial, we will learn how to implement a one-to-many mapping using Hibernate.

1. Setting Up Dependencies:

First, ensure you have Hibernate's dependencies in your project. For Maven users, this primarily means including hibernate-core.

2. Database Tables:

  • department table: To store department details.
  • employee table: To store employee details. It will have a foreign key (department_id) referring to the department table.

3. Mapping Entities:

Department.java:

@Entity
@Table(name="department")
public class Department {

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

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

    @OneToMany(mappedBy="department", cascade=CascadeType.ALL)
    private List<Employee> employees;

    // constructors, getters, setters...
}

Employee.java:

@Entity
@Table(name="employee")
public class Employee {

    @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;

    @ManyToOne
    @JoinColumn(name="department_id")
    private Department department;

    // constructors, getters, setters...
}

Explanation:

  • @OneToMany(mappedBy="department", cascade=CascadeType.ALL): The mappedBy attribute refers to the property name of the association on the owner side (Employee in this case). The cascade attribute specifies what should happen when the Department entity is persisted, updated, or deleted. In this example, any changes to a Department will cascade to its associated Employee records.

  • @ManyToOne: Indicates that it's a many-to-one relationship.

  • @JoinColumn: Specifies the name of the foreign key column.

4. Working with Data:

Saving:

Session session = sessionFactory.getCurrentSession();
session.beginTransaction();

// create a department and employees
Department tempDepartment = new Department("IT");

Employee tempEmployee1 = new Employee("John", "Doe");
Employee tempEmployee2 = new Employee("Mary", "Public");

// associate employees with the department
tempEmployee1.setDepartment(tempDepartment);
tempEmployee2.setDepartment(tempDepartment);

// add employees to the department
tempDepartment.addEmployee(tempEmployee1);
tempDepartment.addEmployee(tempEmployee2);

// save the department (due to CascadeType.ALL, this will also save the employees)
session.save(tempDepartment);

session.getTransaction().commit();

Retrieving:

Session session = sessionFactory.getCurrentSession();
session.beginTransaction();

// fetch department with id=1
Department tempDepartment = session.get(Department.class, 1);

// print employees of the department
for(Employee tempEmployee : tempDepartment.getEmployees()) {
    System.out.println(tempEmployee.getFirstName());
}

session.getTransaction().commit();

5. FetchType:

By default, one-to-many relationships are lazily fetched in Hibernate. This means:

  • When you fetch a Department, the associated Employee records are not fetched until you access the collection (tempDepartment.getEmployees()). This is done to optimize performance.

Conclusion:

Mapping one-to-many relationships in Hibernate is relatively straightforward. By defining your entities correctly and understanding the lifecycle of cascading operations, you can effectively map and manipulate complex relational data in your application. Always remember to decide the fetching strategy based on performance needs (e.g., lazy vs. eager fetching).

  1. Hibernate one-to-many mapping example:

    • One-to-many mapping is used to represent a relationship where one entity has a collection of another entity.
    • Configure the mapping using the @OneToMany annotation.
    // In the parent entity (Department)
    @OneToMany(mappedBy = "department")
    private List<Employee> employees;
    
  2. Configuring one-to-many associations in Hibernate:

    • Configure one-to-many associations in Hibernate using the @OneToMany annotation.
    • Specify the target entity and the mappedBy attribute.
    @OneToMany(mappedBy = "department")
    private List<Employee> employees;
    
  3. Mapping one-to-many relationships with Hibernate annotations:

    • One-to-many relationships can be mapped using annotations by using the @OneToMany annotation on the reference variable in the parent entity.
    @OneToMany(mappedBy = "department")
    private List<Employee> employees;
    
  4. Lazy loading with Hibernate one-to-many mapping:

    • Lazy loading is a technique where associated entities are loaded only when accessed.
    • Use fetch = FetchType.LAZY to enable lazy loading.
    @OneToMany(mappedBy = "department", fetch = FetchType.LAZY)
    private List<Employee> employees;
    
  5. Bidirectional one-to-many mapping in Hibernate:

    • Bidirectional one-to-many mapping involves having a reference in both entities.
    • Use @ManyToOne in the child entity and @OneToMany in the parent entity.
    // In the parent entity (Department)
    @OneToMany(mappedBy = "department")
    private List<Employee> employees;
    
    // In the child entity (Employee)
    @ManyToOne
    @JoinColumn(name = "department_id")
    private Department department;
    
  6. Cascading operations in Hibernate one-to-many mapping:

    • Cascading allows propagating operations (save, update, delete) from one entity to its associated entities.
    • Use cascade attribute in the @OneToMany annotation.
    @OneToMany(mappedBy = "department", cascade = CascadeType.ALL)
    private List<Employee> employees;
    
  7. Fetching strategies in Hibernate one-to-many associations:

    • Hibernate supports different fetching strategies: select, join, subselect.
    • Define the strategy using the fetch attribute.
    @OneToMany(mappedBy = "department", fetch = FetchType.LAZY)
    private List<Employee> employees;
    
  8. HQL queries for one-to-many associations in Hibernate:

    • Use HQL (Hibernate Query Language) to perform queries involving one-to-many associations.
    String hql = "FROM Department d JOIN d.employees e WHERE e.salary > :minSalary";
    Query query = session.createQuery(hql);
    query.setParameter("minSalary", 50000);
    List<Object[]> result = query.list();
    
  9. Handling orphan removal with Hibernate one-to-many mapping:

    • Orphan removal ensures that entities removed from the collection are also removed from the database.
    • Use orphanRemoval = true in the @OneToMany annotation.
    @OneToMany(mappedBy = "department", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Employee> employees;