Hibernate Tutorial
Core Hibernate
Hibernate Mapping
Hibernate Annotations
Hibernate with Spring Framework
Hibernate with Database
Hibernate Log4j
Inheritance Mapping
Many-to-one relationships are common in relational database systems. A classic example is a scenario where multiple employees are associated with one department, establishing a many-to-one relationship between employees and their department.
In this tutorial, we'll see how to map a many-to-one relationship using Hibernate.
Let's consider two entities, Employee
and Department
. An employee is associated with one department, but a department can have multiple employees.
employee
table: To store employee details.department
table: To store department details.The employee
table will have a foreign key (department_id
) referring to the primary key of the department
table.
Make sure you have Hibernate's dependencies in your project. For Maven users, this primarily means including hibernate-core
.
@Entity @Table(name="department") public class Department { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name="id") private int id; @Column(name="name") private String name; // constructors, getters, setters... }
@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(fetch = FetchType.LAZY) @JoinColumn(name="department_id") private Department department; // constructors, getters, setters... }
@ManyToOne
: This annotation indicates a many-to-one relationship.@JoinColumn
: Specifies the name of the foreign key column that refers to the primary key of the table being joined.Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); // create department and employee Department tempDepartment = new Department("IT"); Employee tempEmployee1 = new Employee("John", "Doe"); Employee tempEmployee2 = new Employee("Mary", "Public"); // associate department with employees tempEmployee1.setDepartment(tempDepartment); tempEmployee2.setDepartment(tempDepartment); // save the department and employees session.save(tempDepartment); // this saves the department session.save(tempEmployee1); // this saves employee 1 session.save(tempEmployee2); // this saves employee 2 session.getTransaction().commit();
Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); // fetch employee with id=1 Employee tempEmployee = session.get(Employee.class, 1); // print department of that employee System.out.println(tempEmployee.getDepartment()); session.getTransaction().commit();
FetchType.LAZY
: With this setting, the associated entity (Department in this case) isn't loaded unless it's accessed. This helps to optimize performance by avoiding unnecessary database hits. In our example, when you fetch an employee, the department isn't loaded until you call tempEmployee.getDepartment()
.Mapping many-to-one relationships in Hibernate is straightforward and aligns with the relational model of databases. It's crucial to understand the cascading and fetching strategies, as well as when and how to use them to optimize performance and ensure that the database's state remains consistent with the object model in the application.
Configuring many-to-one associations in Hibernate:
many-to-one
element in the Hibernate XML mapping file or using annotations.<!-- XML Mapping --> <many-to-one name="employee" class="com.example.Employee" column="employee_id" />
// Annotation Mapping @ManyToOne @JoinColumn(name = "employee_id") private Employee employee;
Mapping many-to-one relationships with Hibernate annotations:
@ManyToOne
annotation on the reference variable in the entity class.@ManyToOne @JoinColumn(name = "department_id") private Department department;
Lazy loading with many-to-one associations in Hibernate:
fetch = FetchType.LAZY
to enable lazy loading.@ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "department_id") private Department department;
Bidirectional many-to-one mapping in Hibernate:
mappedBy
attribute in the @ManyToOne
annotation to establish bidirectional mapping.// In Employee class @ManyToOne @JoinColumn(name = "department_id") private Department department; // In Department class @OneToMany(mappedBy = "department") private List<Employee> employees;
Cascading operations in Hibernate many-to-one mapping:
cascade
attribute in the @ManyToOne
annotation.@ManyToOne(cascade = CascadeType.ALL) @JoinColumn(name = "department_id") private Department department;
Fetching strategies in Hibernate many-to-one associations:
select
, join
, subselect
.fetch
attribute.@ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "department_id") private Department department;
HQL queries for many-to-one associations in Hibernate:
String hql = "FROM Employee e WHERE e.department.name = :deptName"; Query query = session.createQuery(hql); query.setParameter("deptName", "IT"); List<Employee> employees = query.list();
Handling foreign key constraints in many-to-one mapping:
@ManyToOne @JoinColumn(name = "department_id", foreignKey = @ForeignKey(name = "FK_EMPLOYEE_DEPARTMENT")) private Department department;