728x90
객체를 테이블에 맞춰 데이터 중심으로 모델링을 하면 협력 관계를 만들 수 없다.
- 테이블은 외래키로 조인을 사용해서 연관된 테이블을 찾는다.
- 따라서 테이블은 외래키 하나만 가지고 양쪽에서 조인을 통하여 연관된 테이블을 찾을 수 있다.
- 객체는 참조를 통해서 연관된 객체를 찾는다.
- 객체는 양쪽 모두 참조 설정을 해야 양방향 매핑이 가능하다.
- 이는 테이블과 객체의 큰 차이점으로 연관관계 매핑을 이해하는 데에 어려움을 야기한다.
객체의 단방향 연관관계
@Entity
public class Member {
@Id
@GeneratedValue
private Long id;
@Column(name = "USERNAME")
private String name;
private int age;
@ManyToOne
@JoinColumn(name = "TEAM_ID") // TEAM 객체와 매핑할 테이블의 컬럼명(외래키)
private Team team;
객체의 양방향 관계
- 객체의 양방향 관계는 사실 양방향 관계가 아니라 서로 다른 단방향 관계 2개이다.
- 객체를 양방향으로 참조하려면 단방향 연관관계 2개를 만들어야 한다.
@Entity
public class Team {
@Id
@GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "team") // 연관관계의 주인이 team임을 지정함
List<Member> members = new ArrayList<Member>();
...
}
객체와 테이블이 관계를 맺는 차이
- 객체의 연관 관계는 단방향 2번의 참조로 이루어진다.
- 객체의 양방향 관계는 정말 양방향이 아니라 서로 다른 단방향 관계 2개로 이루어진 것이다.
- 테이블의 연관관계는 외래키 하나로 방향 구분 없이 이루어진다.
자연스레 드는 생각
- Member 객체나 Team 객체로 외래키를 관리해야한다. 누가 관리해야 할까?
연관관계의 주인(Owner)
양방향 매핑 규칙
- 객체의 두 관계 중에 하나를 연관관계의 주인으로 지정해야한다.
- 테이블은 외래키 하나만 있지만 객체는 연관관계 매핑된 필드가 두 개(team, members)이다.
- JPA 입장에서는 혼란스럽다. 누구를 기준으로 외래키를 업데이트 해야하는지 말이다.
- ex) members에만 값을 세팅하고 team에는 값을 세팅하지 않거나, members에 값을 세팅하지 않고 team에만 값을 세팅했다면?
- 따라서, JPA는 두 객체 중 하나를 기준으로 테이블의 외래키와 매핑하기로 했다.
- 이때 테이블의 외래키와 매핑하는 객체를 연관관계의 주인이라고 한다.
- 결론부터 말하면 외래키가 있는 곳을 연관관계의 주인으로 지정하면 된다.
- 연관 관계의 주인만이 외래키를 등록, 수정할 수 있다.
- 주인이 아닌 쪽은 읽기만 가능하다.
- 주인이 아닌 쪽에서 MappedBy 속성으로 주인을 지정한다.
누구를 주인을 정해야 할까?
- 외래키가 있는 곳을 주인으로 정하면 된다.
- 만약 Member 엔티티의 Team을 연관관계의 주인으로 정하면
- Team 엔티티에서 변경 작업을 했는데 쿼리는 Member 테이블이 변경되는 쿼리가 나가게 된다.(실무에서 헷갈리게 된다.)
- Team 테이블에서 Insert 쿼리를 날리면 Member에서는 update 쿼리가 나가는 등 불필요한 쿼리가 날라가 성능상 좋지 않다.
양방향 매핑 정리
- 단방향 매핑만으로도 이미 연관관계 매핑은 완료된 것이다.
- 양방향 매핑은 반대 방향으로 조회(객체 그래프 탐색) 기능이 추가된 것일 뿐이다.
- JPQL에서 역방향으로 탐색할 일이 많음
- 단방향 매핑을 잘하고 양방향은 필요할 때 추가해도 됨(테이블에 영향을 주지 않음)
- 양방향 매핑 시 연관관계의 주인에 값을 입력하고, 순수한 객체 관계를 고려하면 항상 양쪽 모두 값을 입력해야 한다.
참고
김영한 - 자바 ORM 표준 JPA 프로그래밍
728x90
'[JAVA] > JPA' 카테고리의 다른 글
JPA - 다양한 연관관계 매핑 (0) | 2022.11.28 |
---|---|
JPA - 연관관계 매핑시 고려사항 3가지 (0) | 2022.11.28 |
JPA - 기본 키 매핑 (0) | 2022.11.27 |
JPA - 필드와 컬럼 매핑 (0) | 2022.11.27 |
JPA - 객체와 테이블 매핑 (0) | 2022.11.27 |