-
@ManyToMany 사용 시 주의할 점 (List, Set)JPA 2023. 1. 25. 16:35
@ManyToMany 사용을 되도록 피해야 한다고 배웠다.
그 이유는,
- 개발하다 보면 연결 테이블이 단순히 연결만 하고 끝나지 않는다. 조인 테이블 자체에 주문 시간, 수량 같은 추가 데이터가 많이 들어갈 수 있다.
- 하지만, 매핑 정보만 넣는 것이 가능하고, 추가 정보를 넣는 것 자체가 불가능하다.
- 그리고 중간 테이블이 숨겨져 있기 때문에 예상하지 못하는 쿼리들이 나간다.
이러한 문제점들 때문에 실무에서는 사용하면 안된다고 한다.
해결 방법으로는,
- 연결 테이블용 엔티티를 추가한다. 사실상 연결 테이블을 엔티티로 승격시킨다.
- 그리고 @ManyToMany를 각각 일대다, 다대일로 관계를 맺어준다.
- JPA가 만들어주는 숨겨진 매핑테이블의 존재를 밖으로 꺼내는 것이다.
등이 있다.
나는 그럼에도 다대다 관계를 사용하였는데, 나의 경우 단순히 스터디에서 사용하는 기술들을 다대다 관계로 추가하고 싶은 경우였다.
또한 스터디-기술 사이의 엔티티를 따로 만들어서 추후에 추가될 컬럼은 없을 것이라고 생각되었다.
ManyToMany를 사용할 때의 주의할 점
Article, Category 두 엔티티가 있을 때,
@ManyToMany(mappedBy = "categories") private List<Article> articles = new ArrayList<>();
이와 같이 ManyToMany 관계 시 List를 사용할 경우,
Atricle에 새로운 Category를 삽입할 때에 article_category 테이블에 article_id에 해당하는 모든 관계를 삭제하고, 신규로 생성된 관계를 삽입한다.
Delete from article_category where article_id = ? Insert into article_category (article_id, category_id) values (?, ?) Insert into article_category (article_id, category_id) values (?, ?)
하지만 List 대신 set을 사용할 경우,
@ManyToMany(mappedBy = “categories”) Private Set<Article> articles = new HashSet<>();
List와는 다르게 삭제하고자 하는 Category 1건의 관계만 삭제하고 새로운 1건의 관계만 삽입한다.
Delete from article_category where article_id = ? And category_id = ? Insert into article_category (article_id, category_id) values (?,?)
JPA 에서 ManyToMany 의 관계일때 List와 Set의 차이점을 고려하여 사용해야 할 것 같다.
'JPA' 카테고리의 다른 글
N+1 Select 문제 (0) 2023.02.14 @EntityGraph (0) 2023.02.14 JPA Enum Type (@Enumerated, EnumType) (0) 2023.01.25 JPA의 리턴타입이 Optional인 이유 (0) 2023.01.19