hibernate-006: Unidirectional One-to-Many and Many-to-One in Hibernate (Department ↔ Employee)

Hunor Vadasz-Perhat - Feb 10 - - Dev Community

Unidirectional One-to-Many and Many-to-One using Department and Employee Tables

I'll show you both unidirectional approaches:

  1. Unidirectional @OneToMany → The Department entity knows about Employee, but Employee does NOT know about Department.
  2. Unidirectional @ManyToOne → The Employee entity knows about Department, but Department does NOT know about Employee.

1️⃣ Unidirectional @OneToMany

Entity Definitions

@Entity
public class Department {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @OneToMany
    @JoinColumn(name = "department_id") // ✅ Forces FK in Employee instead of a join table
    private List<Employee> employees;
}
Enter fullscreen mode Exit fullscreen mode
@Entity
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
}
Enter fullscreen mode Exit fullscreen mode

2️⃣ Unidirectional @ManyToOne (Recommended)

✅ This is the best practice: The Employee table has a department_id column, and Department does not have a List<Employee>.

Entity Definitions

@Entity
public class Department {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
}
Enter fullscreen mode Exit fullscreen mode
@Entity
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @ManyToOne
    @JoinColumn(name = "department_id") // ✅ Foreign key column
    private Department department;
}
Enter fullscreen mode Exit fullscreen mode

Generated SQL

This creates only two tables, without an extra join table:

CREATE TABLE department (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255)
);

CREATE TABLE employee (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255),
    department_id BIGINT,
    FOREIGN KEY (department_id) REFERENCES department(id)
);
Enter fullscreen mode Exit fullscreen mode

This is better because:

  • The foreign key (department_id) is stored inside the Employee table.
  • No extra join table is needed.
  • It’s more efficient for querying.

🔥 Conclusion

Approach Uses @OneToMany? Uses @ManyToOne? Foreign Key in Employee? Extra Join Table? Recommended?
Unidirectional @OneToMany ✅ Yes ❌ No ❌ No ✅ Yes ❌ No
Unidirectional @ManyToOne ❌ No ✅ Yes ✅ Yes ❌ No ✅ Yes

🚀 Best practice: Use only @ManyToOne for a unidirectional relationship.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .