Bird
Raised Fist0
Spring Bootframework~3 mins

Why @ManyToMany relationship in Spring Boot? - Purpose & Use Cases

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
The Big Idea

Discover how to effortlessly connect complex data relationships without messy code!

The Scenario

Imagine you have two lists: one of students and one of courses. You want to track which students attend which courses. Manually updating and linking these lists every time a student enrolls or drops a course can get confusing fast.

The Problem

Manually managing these connections means writing lots of code to keep track of every link. It's easy to forget to update one side, causing errors or inconsistent data. This approach is slow, error-prone, and hard to maintain as the data grows.

The Solution

The @ManyToMany annotation in Spring Boot automatically manages these complex links between entities. It handles the join table behind the scenes, keeping both sides in sync without extra code.

Before vs After
Before
List<Course> courses = new ArrayList<>();
courses.add(course1);
student.setCourses(courses);
// Need to update course side manually too
After
@ManyToMany
private Set<Course> courses;
What It Enables

This lets you easily model real-world many-to-many connections in your database with clean, simple code that stays consistent.

Real Life Example

Think of a library system where books can have many authors, and authors can write many books. @ManyToMany helps track these relationships effortlessly.

Key Takeaways

Manually linking many-to-many data is complex and error-prone.

@ManyToMany automates relationship management in Spring Boot.

This leads to cleaner code and reliable data consistency.

Practice

(1/5)
1. What does the @ManyToMany annotation represent in Spring Boot?
easy
A. A relationship where entities inherit from each other.
B. A relationship where one entity has only one of the other entity.
C. A relationship where entities are unrelated.
D. A relationship where each entity can have many of the other entity.

Solution

  1. Step 1: Understand the meaning of @ManyToMany

    The annotation defines a link where each entity can be related to many instances of the other entity.
  2. Step 2: Compare with other relationship types

    Unlike one-to-one or one-to-many, many-to-many allows multiple connections on both sides.
  3. Final Answer:

    A relationship where each entity can have many of the other entity. -> Option D
  4. Quick Check:

    @ManyToMany = many-to-many link [OK]
Hint: Think: many items linked to many others [OK]
Common Mistakes:
  • Confusing with one-to-one or one-to-many
  • Thinking it means inheritance
  • Ignoring the bidirectional nature
2. Which of the following is the correct way to define a join table in a @ManyToMany relationship?
easy
A. @JoinColumn(name = "student_course")
B. @JoinTable(name = "student_course", joinColumns = @JoinColumn(name = "student_id"), inverseJoinColumns = @JoinColumn(name = "course_id"))
C. @Table(name = "student_course")
D. @JoinTable(name = "student_course", joinColumns = @JoinColumn(name = "course_id"), inverseJoinColumns = @JoinColumn(name = "student_id"))

Solution

  1. Step 1: Identify correct @JoinTable usage

    The join table must specify the table name and correctly assign joinColumns and inverseJoinColumns to the owning and inverse sides.
  2. Step 2: Check column names match entities

    joinColumns should refer to the current entity's ID, inverseJoinColumns to the other entity's ID.
  3. Final Answer:

    @JoinTable(name = "student_course", joinColumns = @JoinColumn(name = "student_id"), inverseJoinColumns = @JoinColumn(name = "course_id")) -> Option B
  4. Quick Check:

    @JoinTable with correct joinColumns = A [OK]
Hint: joinColumns = this entity, inverseJoinColumns = other entity [OK]
Common Mistakes:
  • Swapping joinColumns and inverseJoinColumns
  • Using @JoinColumn instead of @JoinTable
  • Omitting joinColumns or inverseJoinColumns
3. Given the following code snippet, what will be the output when printing student.getCourses().size() after adding two courses to the student?
@Entity
class Student {
  @ManyToMany
  Set<Course> courses = new HashSet<>();

  public Set<Course> getCourses() { return courses; }
}

@Entity
class Course {}

Student student = new Student();
Course c1 = new Course();
Course c2 = new Course();
student.getCourses().add(c1);
student.getCourses().add(c2);
System.out.println(student.getCourses().size());
medium
A. 2
B. 0
C. 1
D. Compilation error

Solution

  1. Step 1: Understand the collection type and additions

    The courses field is a HashSet, which allows unique elements. Adding two different Course objects increases size to 2.
  2. Step 2: Confirm no errors in adding elements

    Adding elements to the set is valid and no exceptions occur here.
  3. Final Answer:

    2 -> Option A
  4. Quick Check:

    Two courses added = size 2 [OK]
Hint: HashSet size equals unique added elements [OK]
Common Mistakes:
  • Assuming size is 0 because of missing persistence
  • Confusing with list allowing duplicates
  • Expecting compilation error due to missing annotations
4. Identify the error in this @ManyToMany mapping:
@Entity
class Author {
  @ManyToMany
  Set<Book> books;
}

@Entity
class Book {
  @ManyToMany(mappedBy = "books")
  Set<Author> authors;
}
medium
A. The @ManyToMany annotation is missing @JoinTable on both sides.
B. The mappedBy attribute is incorrectly used on the owning side.
C. The collections are not initialized, causing NullPointerException.
D. The entities must extend a common superclass.

Solution

  1. Step 1: Check collection initialization

    The sets 'books' and 'authors' are declared but not initialized, so they are null by default.
  2. Step 2: Understand impact of null collections

    Trying to add or access elements will cause NullPointerException at runtime.
  3. Final Answer:

    The collections are not initialized, causing NullPointerException. -> Option C
  4. Quick Check:

    Uninitialized sets cause null errors [OK]
Hint: Always initialize collections to avoid null errors [OK]
Common Mistakes:
  • Assuming @JoinTable is mandatory on both sides
  • Confusing owning side with inverse side
  • Thinking inheritance is required
5. You have two entities, Student and Club, with a @ManyToMany relationship. You want to add a new club to a student and ensure both sides reflect this change. Which code snippet correctly updates both sides?
hard
A. student.getClubs().add(club); club.getStudents().add(student);
B. student.getClubs().add(club);
C. club.getStudents().add(student);
D. student.setClubs(Set.of(club));

Solution

  1. Step 1: Understand bidirectional @ManyToMany updates

    Both sides must be updated to keep the relationship consistent in memory.
  2. Step 2: Check which code updates both sides

    student.getClubs().add(club); club.getStudents().add(student); adds the club to the student's clubs and the student to the club's students, syncing both sides.
  3. Final Answer:

    student.getClubs().add(club); club.getStudents().add(student); -> Option A
  4. Quick Check:

    Update both sides for consistency [OK]
Hint: Always update both sides of @ManyToMany [OK]
Common Mistakes:
  • Updating only one side causing stale data
  • Replacing collections without adding
  • Ignoring inverse side updates