N:M 다대다 관계 매핑, 어떻게 풀어낼 것인가?

Shinny·2022년 8월 17일
0

Member와 StudyRoom의 관계 매핑을 지으려고 생각하다보니, 두 엔티티의 관계는 일대다, 다대일 관계가 아니라 다대다임을 알게 되었다. 물론 @ManyToMany를 써서 두 엔티티를 매핑하는 것이 이론적으로 불가능한 것은 아니다.(오히려 편리해보이기도 한다.) 하지만 여기에는 고려할 사항이 몇 가지 더 있었다.

💡 ManyToMany 적용의 실질적 문제들

  • 객체는 Collection을 사용해서 객체만 2개 있어도 다대다 매핑이 가능하다. 하지만 관계형 데이터 베이스는 정규화된 테이블 2개로 다대다 관계를 표현할 수 없다.
  • 편리해보이긴 해도, 중간 테이블이 숨겨져 있어 쿼리가 나가는 것을 예측하기 어렵다.
  • (나중에라도) 필드를 추가적으로 넣을 수 없다. 예를 들어, MemberStudyRoom 엔티티를 만들게 되면 해당 엔티티에 필드값을 추가적으로 넣을 수가 있는데 ManyToMany 관계에서는 그렇게 할 수가 없어서 비즈니스가 커지고 새로운 로직들이 추가될 수록 불편해질 것이다.

이러한 문제점들을 이해하고, 나는 Member와 StudyRoom을 잇는 MemberStudyRoom이라는 엔티티를 만들었다. 객체는 아래와 같이 구성했다.

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

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "MEMBER_ID")
    private Member member;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "STUDYROOM_ID")
    private StudyRoom studyRoom;

    public MemberStudyRoom(Member member, StudyRoom studyRoom) {
        setMember(member);
        setStudyRoom(studyRoom);
    }

    public void setMember(Member member) {
        this.member = member;
        member.getMemberStudyRooms().add(this);
    }

    public void setStudyRoom(StudyRoom studyRoom) {
        this.studyRoom = studyRoom;
        studyRoom.getMemberStudyRooms().add(this);
    }
}

그리고 생성자를 통해서 어떤 Member가 어떤 StudyRoom에 Join할 때 서로에게 연관관계가 잘 매핑될 수 있도록 연관 편의 메소드도 추가해주었다.

profile
비즈니스 성장을 함께 고민하는 개발자가 되고 싶습니다.

0개의 댓글