@ManyToMany 를 실무에서 사용하면 안된다는 얘기를 많이 들었고, 그래서 항상 관계를 풀어서 사용했었다.
이번에 다시 관계를 풀어 사용하면서 왜 풀어야하나 생각해보니 답이 떠오르지 않아 이를 정리해본다.
@ManyToMany
@Entity
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToMany
@JoinTable(
name = "student_course" // 중간 테이블의 이름
)
private List<Course> courses = new ArrayList<>();
// 기본 생성자, getter/setter 생략
}
@Entity
public class Course {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
@ManyToMany(mappedBy = "courses") // Student 엔티티에서의 관계를 매핑
private List<Student> students = new ArrayList<>();
// 기본 생성자, getter/setter 생략
}
@ManyToMany 를 사용하면, Jpa가 자동으로 중간 테이블을 생성해준다.
따라서 @OneToMany , @ManyToOne 을 통해 중간테이블 클래스를 직접 만들어 사용하는 것과 동일한 결과를 얻을 수도 있다.
그럼 왜 @ManyToMany 를 사용하면 안될까?
@ManyToMany를 사용하면 안되는 이유
1. 중간 테이블에 추가 데이터를 추가할 수 없다.
@ManyToMany 를 사용하면, JPA가 중간 테이블을 자동으로 생성해주고 쿼리문도 알아서 처리해준다.
중간 테이블을 개발자가 설정할 수 없게 되므로, 중간 테이블에 추가 정보(생성일, 상태 등)을 저장할 수 없다.
2. 인덱싱을 할 수 없다.
@ManyToMany 의 경우 조회 시 다음과 같이 join이 많아져 성능이 저하될 수 있다.
SELECT s.id, s.name, c.title
FROM student s
JOIN student_course sc ON s.id = sc.student_id
JOIN course c ON sc.course_id = c.id
성능이 좋지 못 한 경우, 중간 테이블에 대해 인덱싱을 통해 어느 정도 성능을 개선할 수 있지만, @ManyToMany 의 경우 중간 테이블에 대해 설정할 수 없으므로 개선이 불가능해진다.
(예를 들어 특정 학생이 수강하는 모든 강의를 조회한다고 하면, 중간 테이블 학생 외래키에 인덱싱을 걸면 더 빠르게 데이터를 찾을 수 있다.)
'Spring > Spring Jpa' 카테고리의 다른 글
LazyInitializationException과 LazyLoading의 동작원리 (0) | 2025.02.19 |
---|---|
OSIV란? (feat.OSIV를 통한 성능 최적화) (0) | 2024.09.25 |
Eager Loading(즉시 로딩) vs Lazy Loading(지연 로딩) 중 어느 전략을 사용해야 할까? (0) | 2024.09.24 |
spring jpa를 활용한 데이터 저장 성능 향상(saveAll(), bulk insert) (2) | 2024.05.16 |