🔹 By default in JPA/Hibernate:
- If you write
@OneToMany
withoutmappedBy
, Hibernate creates a join table to associate the two entities. - A join table is a separate table just to link parent IDs and child IDs → unnecessary if you already have a foreign key.
🔹 Example without mappedBy
(unidirectional):
@Entity
public class Department {
@OneToMany // no mappedBy!
private List<Employee> employees = new ArrayList<>();
}
🔹 What Hibernate does:
Creates an additional table like department_employee
with:
department_employee
--------------------
department_id | employee_id
This join table tracks which employees belong to which department, because Hibernate has no idea that the Employee
table might have a department_id
foreign key.
🔹 Example with mappedBy
(bidirectional):
@Entity
public class Department {
@OneToMany(mappedBy = "department")
private List<Employee> employees;
}
@Entity
public class Employee {
@ManyToOne
@JoinColumn(name = "department_id") // actual foreign key in Employee table
private Department department;
}
🔹 What Hibernate does now:
✅ No join table needed!
✅ Hibernate sees the department
field in Employee
as the owning side, which already maps a foreign key (department_id
) directly in employees
table:
employees
-------------------------
id | name | department_id
🔹 So what does mappedBy
do?
✅ Tells Hibernate which field in the child entity owns the relationship.
✅ Signals: “This one-to-many association should rely on the child’s foreign key column, not a separate join table.”
🔹 Key takeaway:
🟢 With mappedBy
→ Hibernate uses a foreign key in the child table (no join table).
🔴 Without mappedBy
→ Hibernate creates a separate join table to store parent-child associations.
✅ Bottom line:
The mappedBy
attribute in @OneToMany
avoids unnecessary join tables by telling Hibernate to rely on the existing foreign key in the “many” side’s table.