2 분 소요

본 포스트는 Inflearn의 김영한님 강의를 바탕으로 작성했습니다.


객체와 테이블의 패러다임 불일치

먼저 객체와 테이블 사이의 간극을 이해할 필요가 있다. 객체는 참조 를 사용해서 연관된 객체를 찾는다. 그런데 테이블은 외래키 조인을 통해서 연관된 테이블을 찾는다. 때문에 객체를 테이블에 맞춰서 설계를 하면 객체간의 협력 관계를 만들 수 없다. MemberTeam 사이의 관계를 통해 이해해보자.

여기서 하나의 Member 는 하나의 Team 에만 속할 수 있다고 가정하자. (1:N)


테이블에 맞춘 객체 설계

  • Member
@Entity
public class Member {
  @Id @GeneratedValue
  private Long id;
  
  //Team team 과 같이 참조를 가지는 것이 아니라 식별자를 가진다.
  @Column(name = "TEAM_ID")
  private Long teamId;
}


  • Team
@Entity
public clas Team {
  @Id @GeneratedValue
  private Long id;
  private String name;
}


  • Team 조회
//member.getTeam()과 같이 바로 조회할 수 없고 id를 구한 후 이를 통해 한번 더 조회해야 한다.
Long TeamId = member.getTeamId();
Team team = em.find(Team.class, TeamId)


위와 같은 경우가 테이블에 맞춰서 객체를 설계한 케이스이다. Member 에서 Team 을 참조로 가지고 있는 것이 아니라 외래키를 그대로 들고 있다.

이렇게 되면 Member에서 Team을 조회할 때, 참조로 바로 Team을 조회할 수 없고 ID를 통해서 다시 조회해야 한다. 이는 객체 지향적인 방법이 아니다.

ORM을 통해서 이러한 패러다임의 불일치를 해결할 수 있다. 객체는 객체대로 모델링하면 가운데서 ORM이 알맞게 매핑해준다.



객체지향 모델링

@Entity
public class Member {
  @Id @GeneratedValue
  private Long id;
  
	@ManyToOne
  @JoinColumn(name = "TEAM_ID")
  private Team team;
}


위 코드를 보면 Member에서 Team 객체를 참조로 가지고 있다. 그런데 Member 테이블에서는 외래키로 TEAM_ID를 가지고 있을 것이다. 이런 차이를 매핑해주는 것이 바로 ORM 이다. 아래 그림을 보자.

img1

JPA는 Member 객체에 있는 Team 참조를 Member Table 에 TEAM_ID 라는 외래키로 매핑해준다. 이 때 외래키 이름을 지정해줘야 하는데 @JoinColumn 을 통해 지정해줄 수 있다.



양방향 매핑

이제 양방향 매핑에 대해서 탐구해보자. 양방향 매핑일 때는 고려해야 할 점이 좀 있다. 객체는 양방향 매핑을 하려면 양쪽에 참조를 가져야 한다. 그런데 테이블은 외래키 하나로 조인을 통해서 양쪽을 이동할 수 있다.

img2

위 그림을 보면 Member 객체에 있는 Team, Team 객체에 있는 Member 참조값을 통해서 양쪽을 왔다갔다 할 수 있다.

그런데 테이블은 MEMBER 테이블에 있는 TEAM_ID라는 외래키를 통해서 양쪽을 이동한다.

사실 객체는 양방향을 구현하려면 단방향 두개가 있어야 하는 것이고 테이블은 외래키 하나만 있으면 되는 것이다. 때문에 두 객체 중 한쪽에서 외래키를 관리해야 한다.



연관관계의 주인

객체의 두 관계중 하나를 연관관계의 주인으로 설정하고 주인쪽에서 외래키를 관리해야 한다. 반대쪽(거울)에서는 오직 읽기만 가능하다.

규칙은 간단하다. 외래키를 가지고 있는 곳을 주인으로 설정하면 된다. 1:N관계라면 무조건 N쪽에 외래키가 존재하기 때문에 N쪽을 주인으로 설정하면 된다. 거울쪽에는 mappedBy 설정을 해주면 된다.

  • 주의점 : 거울쪽에서 수정을 하더라도 udpate query가 날아가지 않는다. (단순 조회만 가능)
    • 객체 관점에서 보면 양쪽 다 변경되는 것이 맞기 때문에 다 변경해주자.



참고 사이트 출처

  • https://www.inflearn.com/course/ORM-JPA-Basic/dashboard

태그: , ,

카테고리:

업데이트: