JPA @ManyToMany Annotation

In this blog post, we will learn everything about JPA @ManyToMany annotation with an example.

@ManyToMany Annotation Overview

The @ManyToMany annotation in JPA is used to map many-to-many relationships between two entities. It indicates that multiple instances of the source entity are associated with multiple instances of the target entity, forming a bidirectional relationship.

When using @ManyToMany, you can customize the behavior of the relationship using several attributes. Here are the most commonly used attributes of the @ManyToMany annotation: 

targetEntity: 

Specifies the target entity class to which the relationship is mapped. It is required when the target entity is not directly inferred from the type of the collection. 

Example: @ManyToMany(targetEntity = Course.class) 

fetch: 

Defines the fetching strategy for the association. It determines when the associated entities should be loaded from the database. Two common options are FetchType.LAZY (loads the entities on-demand when accessed) and FetchType.EAGER (loads the entities immediately with the parent entity). 

Example: @ManyToMany(fetch = FetchType.LAZY) 

cascade: 

Specifies the cascade operations that should be propagated from the parent entity to the associated entities. Use the CascadeType enum to specify one or more cascade types, such as CascadeType.ALL, CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH, and CascadeType.REMOVE.

Example: @ManyToMany(cascade = CascadeType.ALL) 

mappedBy: 

Defines the inverse side of the relationship. It represents the field in the target entity that owns the relationship (i.e., the field that contains the reference to the source entity). It is used when dealing with bidirectional relationships and must match the name of the field in the target entity. 
Example: @ManyToMany(mappedBy = "students") 

@ManyToMany Annotation

Let's consider an example where we have a Student entity and a Course entity. Each student can enroll in multiple courses, and each course can have multiple students. To map this many-to-many relationship, we use the @ManyToMany annotation.

Student JPA Entity

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

    // Constructors, getters, setters, etc.
}

Course JPA Entity

@Entity
public class Course {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

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

    // Constructors, getters, setters, etc.
}
In this example, the Student entity has a courses field annotated with @ManyToMany, while the Course entity has a students field annotated with @ManyToMany(mappedBy = "courses"). The mappedBy attribute on the Course entity refers to the name of the field in the Student entity that owns the relationship.

To persist the many-to-many relationship, we use the @JoinTable annotation to define the join table that holds the associations between students and courses. The join table serves as an intermediary table to store the relationships between the entities. 

The @ManyToMany relationship allows bidirectional mapping, meaning that both entities are aware of the relationship. By defining the association on both sides, we can easily navigate from students to their enrolled courses and vice versa. 

Conclusion

The @ManyToMany annotation in JPA is a powerful tool for mapping many-to-many relationships between entities. With the @ManyToMany annotation, JPA streamlines the handling of many-to-many relationships, providing a straightforward approach to creating flexible and efficient data models in Java applications.

Complete Many-to-Many Mapping Example

References

Comments