김영한님의 <자바 ORM 표준 JPA 프로그래밍> 책을 정리한 내용입니다.
- 방향(Direction): 단방향, 양방향이 있다. 둘 중 한 쪽만 참조하는 것을 단방향 관계라고 하고, 양쪽 모두 서로 참조하는 것을 양방향 관계라 한다. 방향은 객체관계에만 존재하고 테이블 관계는 항상 양방향이다.
- 다중성(Multiplicity): 다대일, 일대다, 일대일, 다대다 다중성이 있다.
- 연관관계의 주인(owner): 객체를 양방향 연관관계로 만들면 연관관계의 주인을 정해야 한다.
객체 연관관계 vs 테이블 연관관계
- 객체는 참조(주소)로 연관관계를 맺는다.
- 테이블은 외래 키로 연관관계를 맺는다.
객체 연관관계와 테이블 연관관계의 가장 큰 차이
참조를 통한 연관관계는 언제나 단방향이다. 객체관계에서 양방향 연관관계를 만든다는 것은 서로 다른 단방향 관계 2개를 만든다는 것이다.
반면에 테이블은 외래 키 하나로 양방향으로 조인할 수 있다.
객체는 참조를 사용해서 연관관계를 탐색할 수 있는데 이것을 객체 그래프 탐색이라 한다.
연관관계를 매핑하기 위한 어노테이션
: 연관관계를 매핑하기 위해서는 다중성을 나타내는 어노테이션을 꼭 사용해야 한다.
@ManyToOne: 다대일(N:1) 연관관계를 표현
@JoinColumn: 외래키를 매핑할 때 사용한다. name 속성에 매핑할 외래 키 이름을 지정한다.
다대일의 양방향 연관관계 매핑을 위해서는 @OneToMany 어노테이션을 사용해야 한다.
객체에는 양방향 연관관계라는 것이 없다. 서로 다른 단방향 연관관계 2개를 양방향스럽게 사용할 뿐이다.
양방향 연관관계를 만들 경우 객체의 연관관계를 관리하는 포인트는 이처럼 두 곳으로 늘어난다.
엔티티를 양방향 연관관계로 설정하면 객체의 참조는 둘인데 외래 키는 하나다. 따라서 둘 사이에 차이가 발생한다.
이러한 차이로 인해 JPA에서는 두 객체 연관관계 중 하나를 정해서 테이블의 외래키를 관리해야 하는데 이것을 연관관계의 주인이라 한다.
연관관계의 주인만이 데이터베이스 연관관계와 매핑되고 외래 키를 관리(등록, 수정, 삭제)할 수 있다.
반면에 주인이 아닌 쪽은 읽기만 할 수 있다.
연관관계의 주인을 정한다는 것을 사실 외래 키 관리자를 선택하는 것이다.
연관관계 설정 방법
- 연관관계 주인은 mappedBy 속성을 사용하지 않는다.
- 주인이 아니면 mappedBy 속성을 사용해서 속성의 값으로 연관관계의 주인을 지정해야 한다.
데이터베이스 테이블의 다대일, 일대다 관계에서는 항상 다 쪽이 외래키를 가진다. 다 쪽인 @ManyToOne은 항상 연관관계의 주인이 되므로 mappedBy를 설정할 수 없다. 따라서 @ManyToOne에는 mappedBy 속성이 없다.
객체 관점에서 연관관계의 양쪽 방향에 모두 값을 입력해주는 것이 안전하다.
이때 연관관계 편의 메서드를 사용해서 메서드 하나로 양쪽 모두에 값을 설정해주는 것이 좋다.
- 단방향 매핑만으로 테이블과 객체의 연관관계 매핑은 이미 완료되었다.
- 단방향을 양방향으로 만들면 반대 방향으로 객체 그래프 탐색 기능이 추가된다.
- 양방향 연관관계를 매핑하려면 객체에서 양쪽 방향을 모두 관리해야 한다.
양방향 매핑은 복잡하다.
우선 단방향 매핑을 사용하고 반대 방향으로 객체 그래프 탐색 기능이 필요할 때 양방향을 사용하도록 코드를 추가해도 된다.