ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • @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
Designed by Tistory.