[JPA] 연관 관계 매핑

김용현·2023년 12월 19일
0

JPA

목록 보기
3/12

본 포스트는 김영한 님의 자바 ORM 표준 JPA 프로그래밍 강의를 토대로 작성하였습니다.

연관 관계 매핑

객체 지향에서는 객체가 다른 객체를 들고 있을 수 있다. 이를 데이터 베이스 상에서 구현하는 것이 외래 키 참조인데, 이를 JPA에서 어떻게 구현하는 지 알아보자.

단 방향 매핑

먼저 한 쪽으로만 관계를 맺는 매핑을 알아보자.

다음처럼 Member Entity 에서 Team Entity 객체를 갖고 싶다면 해당 객체에 @ManyToOne, @JoinColumn을 붙여주면 된다. 이 때 @ManyToOne 말고도 @OneToOne,
@ManyToMany, @OneToMany 등 참조 관계에 따라 적절한 어노테이션을 붙이면 된다.

@JoinColumn의 의미는 FK를 어떤 Column을 이용할 것인지 지정하는 어노테이션이다.

그렇게 연관 관계를 맺었다면 다음과 같이 바로 객체에서 다른 객체를 참조할 수 있다.

양 방향 매핑

객체와 데이터 베이스는 매핑을 맺는 관계가 사뭇 다르다. 그 차이를 정확히 이해하는 것이 중요하다.

다음 그림들을 보면 객체 간의 연관관계는 단방향 2개로 이루어짐을 알 수 있다. 그러나 테이블 연관관계는 TEAM_ID 라는 값 하나로 연결되어 있음을 알 수 있다.

따라서 연관 관계를 맺으려면 테이블 관계를 맺는 일을 해야하므로 Member와 Team Entity 중 한 곳에서 외래 키를 관리해야 한다.

그래서 연관관계의 주인 개념이 등장하게 되는데,

JPA에서는 연관관계의 주인이 아닌 Entity 객체는 연관 객체를 이용하여 값을 수정하더라도 db에 반영되지 않는다.(조회만 가능)

그럼 누가 연관관계의 주인인가❓

외래키가 있는 곳 = 다 대 1 관계에서 다인 곳을 주인으로 설정하는 것이 좋다.

코드로 적용하는 방법은

<Member Entity 클래스>

<Team Entity 클래스>

요렇게 연관관게를 맺으면 된다.

왜 외래키를 들고 있는 테이블과 매핑 된 Entity 객체가 주인인가❗️

예를 들어 위의 예시의 경우 Team이 연관 관계의 주인이 된다면 members에 변경이 있으면 쿼리가 나갈 때 Team 테이블이 아닌 Member 테이블에 관한 쿼리가 날아가게 된다. (변경한 member 테이블의 FK 값을 변경해야하니까) 이렇게 되면 헷갈리게 된다. 따라서 Member를 주인으로 정해서 member의 Team을 변경하고 Member 테이블에 대한 쿼리가 나가도록 해야한다.

꼭 기억해두자!!!!!

양 방향 매핑 시 많이 하는 실수

Team team = new Team();
team.setName("TeamA");
em.persist(team);

Member member = new Member();
member.setName("member1");

//역방향(주인이 아닌 방향)만 연관관계 설정
team.getMembers().add(member);
em.persist(member);

다음처럼 member가 연관관계 주인인데 team 객체로 member 를 add 하고 있다.
이 경우 아무런 일도 일어나지 않는다.

그러나 이처럼 실수할 확률도 있고 객체 지향적인 측면에서 봤을 때는 양 쪽 다 그냥 세팅해주는 것이 좋다.
즉 member.setTeam(team) 하고 team.getMembers().add(member)를 둘 다 해주는 것이 좋다.

여기서 둘 다 하기 번거롭기도 하고 실수도 줄이려면 연관 관계 편의 메소드를 만드는 것도 좋은데,

예를 들어,

public void setTeam(Team team) {
        this.team = team;
    }
    
이 코드를
public void changeTeam(Team team) {
        this.team = team;
        team.getMembers().add(this)
    }
이렇게 바꾼다.

이렇게 하면 member.changeTeam()만 호출하더라도 둘 다 바뀌므로 실수할 확률이 줄어든다. 또한 setTeam의 경우 자바 관례이므로 메소드 이름을 바꾸어 알기 쉽게 하도록 한다.

정리

지금까지 단방향과 양방향 매핑에 대해 알아봤다.

  • 연관관계의 주인은 외래키를 갖고 있는 쪽이다!
  • 김영한 님은 중요한 것은 설계 단계에서 일단 단방향 매핑으로 모든 설계를 끝내고 나중에 개발 단계에서 필요할 때 양방향으로 바꾸는 것이 좋다고 추천한다!
  • mappedBy가 있는 곳이 주인이 아닌 곳이다.
profile
평생 여행 다니는게 꿈 💭 👊 😁 🏋️‍♀️ 🦦 🔥

0개의 댓글