← Back to Questions
Spring Boot

What is @ManyToMany mapping?

Learn What is @ManyToMany mapping? with simple explanations, real-time examples, interview tips and practical use cases.

What is @ManyToMany Mapping in JPA?

@ManyToMany is a JPA annotation used to define a many-to-many relationship between two entity classes.

It means:

β€œMany records in one table can be associated with many records in another table.”

In simple words:

  • Many entities β†’ Many related entities
  • Multiple database rows β†’ Multiple related rows

Real-Life Example of Many-to-Many Relationship

Common examples:

  • Many students enroll in many courses
  • Many users have many roles
  • Many products belong to many categories

Database Example

students Table

id student_name
1 Naresh

courses Table

id course_name
101 Spring Boot
102 Microservices

student_courses Table

student_id course_id
1 101
1 102

Here:

  • One student can enroll in multiple courses
  • One course can contain multiple students

Why @ManyToMany Mapping is Needed

Without relationship mapping:

  • Developers must manually manage join tables
  • Complex JOIN queries increase
  • Object relationships become difficult

@ManyToMany simplifies:

  • Relationship management
  • Join table handling
  • Automatic joins
  • Object navigation

Basic @ManyToMany Example

Student Entity

@Entity
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String studentName;

    @ManyToMany
    @JoinTable(
        name = "student_courses",

        joinColumns = @JoinColumn(
            name = "student_id"
        ),

        inverseJoinColumns = @JoinColumn(
            name = "course_id"
        )
    )
    private List<Course> courses;
}

Course Entity

@Entity
public class Course {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String courseName;
}

What is @JoinTable?

@JoinTable specifies the intermediate join table used for many-to-many relationships.


Join Table Structure

@JoinTable(
    name = "student_courses"
)

creates:

student_courses

table automatically.


What are joinColumns?

joinColumns represent the current entity foreign key.


Example

joinColumns = @JoinColumn(
    name = "student_id"
)

What are inverseJoinColumns?

inverseJoinColumns represent the related entity foreign key.


Example

inverseJoinColumns = @JoinColumn(
    name = "course_id"
)

Generated Database Structure

student_courses Table

CREATE TABLE student_courses (

    student_id BIGINT,

    course_id BIGINT,

    FOREIGN KEY (student_id)
    REFERENCES students(id),

    FOREIGN KEY (course_id)
    REFERENCES courses(id)

)

How @ManyToMany Works Internally

  1. Hibernate detects relationship annotations
  2. Join table is created automatically
  3. Foreign keys are mapped
  4. JOIN queries are generated automatically

Saving Many-to-Many Data

Course course1 = new Course();

course1.setCourseName("Spring Boot");

Course course2 = new Course();

course2.setCourseName("Microservices");

Student student = new Student();

student.setStudentName("Naresh");

student.setCourses(
        List.of(course1, course2)
);

studentRepository.save(student);

Generated SQL Example

INSERT INTO students(student_name)
VALUES ('Naresh');

INSERT INTO courses(course_name)
VALUES ('Spring Boot');

INSERT INTO courses(course_name)
VALUES ('Microservices');

INSERT INTO student_courses(student_id, course_id)
VALUES (1, 101);

INSERT INTO student_courses(student_id, course_id)
VALUES (1, 102);

Fetch Data Example

Student student =
        studentRepository.findById(1L).get();

List<Course> courses =
        student.getCourses();

Bidirectional Many-to-Many Mapping

Both entities can reference each other.


Student Entity

@Entity
public class Student {

    @Id
    private Long id;

    @ManyToMany
    @JoinTable(
        name = "student_courses",
        joinColumns = @JoinColumn(name = "student_id"),
        inverseJoinColumns = @JoinColumn(name = "course_id")
    )
    private List<Course> courses;
}

Course Entity

@Entity
public class Course {

    @Id
    private Long id;

    @ManyToMany(mappedBy = "courses")
    private List<Student> students;
}

What Does mappedBy Mean?

mappedBy specifies:

  • The inverse side of the relationship
  • Which entity owns the relationship

Owning Side vs Inverse Side

Type Description
Owning Side Contains @JoinTable
Inverse Side Contains mappedBy

Default Fetch Type

The default fetch type for:

@ManyToMany

is:

FetchType.LAZY

LAZY Fetch Example

@ManyToMany(fetch = FetchType.LAZY)

Related data loads only when accessed.


EAGER Fetch Example

@ManyToMany(fetch = FetchType.EAGER)

Related data loads immediately.


LAZY vs EAGER Fetching

Feature LAZY EAGER
Loading Time On demand Immediate
Performance Better Can be slower
Memory Usage Lower Higher

Cascade Types in @ManyToMany

Cascade operations automatically apply persistence actions to related entities.


Cascade Example

@ManyToMany(
    cascade = CascadeType.ALL
)

Advantages of @ManyToMany Mapping

  • Simplifies many-to-many relationships
  • Automatic join table handling
  • Easy navigation between entities
  • Reduces manual SQL joins
  • Improves maintainability

Disadvantages of Improper Mapping

  • Complex joins
  • N+1 query problem
  • Performance overhead
  • Large object graphs
  • Circular serialization issues

What is N+1 Query Problem?

N+1 problem occurs when:

  • One query fetches parent entities
  • Additional queries repeatedly fetch related entities

This can reduce performance significantly.


Best Practices for @ManyToMany

  • Prefer LAZY fetching
  • Use DTOs for API responses
  • Avoid unnecessary bidirectional mapping
  • Optimize JOIN queries
  • Use pagination for large collections

Real-Time Example in Role-Based Security

Security systems often contain:

  • Many users β†’ Many roles

Example:

  • User can have ADMIN and USER roles
  • ADMIN role can belong to many users

This is implemented using:

@ManyToMany

Difference Between @ManyToMany and @OneToMany

Feature @ManyToMany @OneToMany
Relationship Many ↔ Many One β†’ Many
Join Table Required Not always required
Example Students ↔ Courses Customer β†’ Orders

Common Interview Questions on @ManyToMany

What is @ManyToMany mapping?

It defines a many-to-many relationship between entities.

Why is a join table needed?

Because many-to-many relationships require mapping records between two tables.

What is @JoinTable?

It specifies the join table used in many-to-many relationships.

What is the default fetch type for @ManyToMany?

LAZY.

What is mappedBy?

It specifies the inverse side of the relationship.


Conclusion

@ManyToMany is an important relationship annotation in JPA and Hibernate.

It helps developers:

  • Handle complex relationships
  • Manage join tables automatically
  • Reduce manual SQL joins
  • Build scalable enterprise applications

Understanding @ManyToMany is essential for Spring Boot developers because enterprise applications heavily rely on many-to-many relationships for proper database design and object mapping.

Why this Spring Boot question is important?

This interview question helps candidates understand real-time backend development concepts, practical problem solving, coding fundamentals, system design basics and production-ready application behavior.

Practice this question carefully for Java backend roles, Spring Boot developer interviews, microservices interviews, company interviews and full-stack developer preparation.

About the Author

Naresh Kumar is a Senior Java Backend Engineer with experience building enterprise applications using Java, Spring Boot, Microservices, Docker, Kubernetes and Cloud technologies.