DEV Community

Hunor Vadasz-Perhat
Hunor Vadasz-Perhat

Posted on

hibernate-007: Bidirectional One-to-Many & Many-to-One in Hibernate (Department ↔ Employee)

Bidirectional One-to-Many & Many-to-One in Hibernate (Department ↔ Employee)


🚀 1️⃣ Bidirectional One-to-Many & Many-to-One

✅ In a bidirectional relationship:

  • The "many" side (Employee) owns the relationship (because it holds the foreign key).
  • The "one" side (Department) is the inverse side and uses mappedBy to refer to the owning side.

📌 Step 1: @ManyToOne (Owning Side - Employee)

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

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

✅ The Employee table gets a department_id foreign key.


📌 Step 2: @OneToMany(mappedBy = "department") (Inverse Side - Department)

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

    @OneToMany(mappedBy = "department") // ✅ Refers to Employee's `department` field
    private List<Employee> employees = new ArrayList<>();
}
Enter fullscreen mode Exit fullscreen mode

mappedBy = "department" tells Hibernate:

  • "The foreign key is already in Employee.department."
  • "Do not create an extra join table."

🔥 Generated SQL (No 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 column
    FOREIGN KEY (department_id) REFERENCES department(id)
);
Enter fullscreen mode Exit fullscreen mode

Correct design! The foreign key is stored in Employee.department_id, and no join table is created.


🚀 2️⃣ How to Use the Bidirectional Relationship in Java

📌 Saving Data

Department department = new Department();
department.setName("IT Department");

Employee emp1 = new Employee();
emp1.setName("Alice");
emp1.setDepartment(department); // ✅ Set reference in Employee

Employee emp2 = new Employee();
emp2.setName("Bob");
emp2.setDepartment(department);

List<Employee> employees = new ArrayList<>();
employees.add(emp1);
employees.add(emp2);

department.setEmployees(employees); // ✅ Set reference in Department

entityManager.persist(department);
entityManager.persist(emp1);
entityManager.persist(emp2);
Enter fullscreen mode Exit fullscreen mode

Both Department and Employee are linked properly.


📌 Querying the Relationship

Get Employees for a Department

Department dept = entityManager.find(Department.class, 1L);
List<Employee> employees = dept.getEmployees();
employees.forEach(emp -> System.out.println(emp.getName()));
Enter fullscreen mode Exit fullscreen mode

Get Department for an Employee

Employee emp = entityManager.find(Employee.class, 10L);
System.out.println(emp.getDepartment().getName());
Enter fullscreen mode Exit fullscreen mode

Both queries work because the relationship is bidirectional.


🚀 3️⃣ Summary: Unidirectional vs. Bidirectional

Feature Unidirectional @OneToMany Unidirectional @ManyToOne Bidirectional (@OneToMany + @ManyToOne)
@OneToMany used? ✅ Yes (But Creates Extra Table) ❌ No ✅ Yes (mappedBy prevents join table)
@ManyToOne used? ❌ No ✅ Yes (Owning Side) ✅ Yes (Owning Side)
Uses @JoinColumn? ❌ No ✅ Yes ✅ Yes (In @ManyToOne)
Foreign key in Employee table? ❌ No ✅ Yes ✅ Yes
Extra join table? ✅ Yes (Unwanted) ❌ No ❌ No

Best Practice: Use Bidirectional @OneToMany + @ManyToOne


Heroku

Build apps, not infrastructure.

Dealing with servers, hardware, and infrastructure can take up your valuable time. Discover the benefits of Heroku, the PaaS of choice for developers since 2007.

Visit Site

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs