A many-to-many mapping models a relationship where multiple instances of one entity can relate to multiple instances of another entity, and vice versa — like a student can enroll in many courses, and a course can have many students.
In relational databases, many-to-many relationships always require a join table, since neither side can hold a simple foreign key to represent multiple references.
🔹 Real-world examples:
- Students ↔ Courses
- Users ↔ Roles
- Authors ↔ Books
🔹 How to map many-to-many in Hibernate (JPA annotations):
You use @ManyToMany
on both entities, optionally with @JoinTable
to customize the join table details.
✅ Example: Student ↔ Course
@Entity
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToMany
@JoinTable(
name = "student_course",
joinColumns = @JoinColumn(name = "student_id"),
inverseJoinColumns = @JoinColumn(name = "course_id")
)
private List<Course> courses = new ArrayList<>();
// getters and setters
}
@Entity
public class Course {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
@ManyToMany(mappedBy = "courses")
private List<Student> students = new ArrayList<>();
// getters and setters
}
🔹 What happens in the database:
Hibernate automatically creates a join table like:
student_course
------------------------
student_id | course_id
Each row in this join table links one student to one course, enabling the many-to-many association.
🔹 Bidirectional mapping:
- The
mappedBy
attribute inCourse.students
points to thecourses
field inStudent
. - This tells Hibernate which side owns the relationship and avoids creating two join tables.
🔹 How to use it in code:
Student student = new Student();
student.setName("Alice");
Course course1 = new Course();
course1.setTitle("Math");
Course course2 = new Course();
course2.setTitle("Physics");
// Link both sides of the relationship
student.getCourses().add(course1);
student.getCourses().add(course2);
course1.getStudents().add(student);
course2.getStudents().add(student);
session.persist(student); // cascades can optionally persist courses
🔹 Key points:
✅ Join table is required for all many-to-many mappings → no direct foreign key can represent it.
✅ Supports both unidirectional (one side knows about the other) and bidirectional (both sides know about each other) mappings.
✅ Can customize the join table name and columns using @JoinTable
.
✅ Key takeaway:
Many-to-many mapping in Hibernate models associations where multiple entities on both sides can relate to each other, using a join table mapped with @ManyToMany
.