Jinnie devlog

@ManyToMany 사용 시 주의할 점 (List, Set) 본문

JPA

@ManyToMany 사용 시 주의할 점 (List, Set)

Jinnnie 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