DEV Community

Hunor Vadasz-Perhat
Hunor Vadasz-Perhat

Posted on

hibernate-010: Bidirectional One-to-Many & Many-to-One in Hibernate

πŸš€ Bidirectional One-to-Many & Many-to-One in Hibernate

Now, let’s fully explore bidirectional One-to-Many and Many-to-One relationships with real examples, database schema, and queries.


πŸ“Œ 1️⃣ What is a Bidirectional One-to-Many & Many-to-One?

  • One parent entity has multiple child entities (One-to-Many).
  • Each child entity belongs to one parent entity (Many-to-One).
  • The "Many" side owns the foreign key, and the "One" side is mapped using mappedBy.

βœ… Best Practice

  • The child (Many) owns the relationship (@ManyToOne with @JoinColumn).
  • The parent (One) just references it (@OneToMany(mappedBy = "field")).

πŸ“Œ 2️⃣ Example: Department ↔ Employee

  • One Department has many Employees (@OneToMany).
  • Each Employee belongs to one Department (@ManyToOne).

βœ… Step 1: Define @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 in Employee table
    private Department department;
}
Enter fullscreen mode Exit fullscreen mode

βœ… The department_id foreign key is stored in Employee.


βœ… Step 2: Define @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.department
    private List<Employee> employees = new ArrayList<>();
}
Enter fullscreen mode Exit fullscreen mode

βœ… mappedBy = "department" tells Hibernate:

  • "The foreign key is already in Employee.department_id."
  • "Don’t create an extra join table."

πŸ“Œ 3️⃣ Database Schema (No 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 column
    FOREIGN KEY (department_id) REFERENCES department(id)
);
Enter fullscreen mode Exit fullscreen mode

βœ… The foreign key is only in Employee.department_id, keeping the relationship correct.


πŸ“Œ 4️⃣ Saving Data in Hibernate

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

department.getEmployees().add(emp1); // βœ… Set reference in Department
department.getEmployees().add(emp2);

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

πŸš€ Now both Department and Employee are correctly linked!


πŸ“Œ 5️⃣ Querying Both Directions

βœ… Get Employees from Department

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

βœ… Get Department from Employee

Employee emp = entityManager.find(Employee.class, 10L);
System.out.println(emp.getDepartment().getName()); // βœ… Works!
Enter fullscreen mode Exit fullscreen mode

βœ… Both queries work because the relationship is bidirectional.


πŸ“Œ 6️⃣ Summary: One-to-Many & Many-to-One

Feature One-to-Many (Department) Many-to-One (Employee)
@OneToMany(mappedBy = "department") βœ… Yes ❌ No
@ManyToOne used? ❌ No βœ… Yes
@JoinColumn(name = "fk_column") ❌ No βœ… Yes
Foreign key location? ❌ Not in Department βœ… In Employee.department_id
Extra join table? ❌ No ❌ No
Reference back? βœ… Yes βœ… Yes

βœ… Best Practice: Use bidirectional @OneToMany + @ManyToOne to avoid unnecessary join tables and keep data consistent.


Happy coding! πŸš€

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)

Heroku

This site is built on Heroku

Join the ranks of developers at Salesforce, Airbase, DEV, and more who deploy their mission critical applications on Heroku. Sign up today and launch your first app!

Get Started