핵심은 객체와 관계형 데이터베이스의 패러다임 불일치
양방향 연관관계와 연관관계의 주인
테이블은 방향이란 개념이 없다. 외래키 자체로 양방향 관계를 가질 수 있다.
하지만, 객체는 참조의 개념이기에 해당 객체를 서로 참조시켜야만 양방향 관계를 가질 수 있다.
연관관계의 주인과 mappedBy
객체와 테이블 간에 연관관계를 맺는 차이를 이해해야 한다.
객체와 테이블이 관계를 맺는 차이
객체 연관관계 = 2개
- 회원 → 팀 연관관계 1개 (단방향)
- 팀 → 회원 연관관계 1개 (단방향)
객체의 양방향 관계는 사실 양방향 관계가 아니라 서로 다른 단 뱡향 관계 2개 이다.
사실 양방향이 의미하는 바는 단방향으로 두개 모두 연결하는 것이다.
테이블 연관관계 = 1개
- 회원 ↔ 팀 연관관계 1개 (양방향)
테이블은 외래 키 하나로 두 테이블의 연관관계를 관리한다
외래키 하나로 양쪽 데이터 모두 접근할 수 있다. (사실상 방향이 존재하지 않는다.)
객체의 연관관계의 경우 사실상 2개의 단방향 연결 (참조) 시키도록 하기 때문에,
두 방향 중 어떤 곳에서 외래키를 관리해야하는지 결정해주어야 한다.
이것이 바로 연관관계의 주인 설정이다.
연관관계의 주인
- 객체의 두 관계 중 하나를 연관관계의 주인으로 지정
- 연관관계의 주인만이 외래 키를 관리 (등록, 수정)
- 주인이 아닌 방향은 읽기만 가능
- 주인은 mappedBy 속성 사용하지 않음
- 주인이 아니면 mappedBy 속성으로 주인 지정
※ 외래키가 있는 곳을 주인으로 정해라
양방향 매핑 시 가장 많이 하는 실수
연관관계의 주인에 값을 입력하지 않음
양방향 매핑 시 연관관계의 주인에 값을 입력해야 한다.
1차 캐시를 고려한 (순수한 객체 관계) 항상 양쪽 모두 값을 참조시켜야만 한다.
※ 연관관계 편의 메서드를 만들어 사용해라
한 쪽에서만 정의하여 사용하는 것이 좋음 (꼭 주인이 아니더라도 정의하여도 됌 다만 한 곳에서만)
단순 setter 가 아닌 해당 비즈니스 로직을 알 수 있도록 정의하는 것이 좋음
※ 주의 사항
양방향 매핑 시에 무한 루프를 조심하자 - toString, Lomobk, JSON 생성 라이브러리(엔티티를 바로 응답 시 자주 생김)
참고로 Entity를 Controller 에서 직접 반환하는 일들은 없도록 하자.
위와 같은 순환 참조 문제 등 발생할 수 있는 위험이 있을 수 있다.
양방향 매핑 정리
- 단방향 매핑만으로도 이미 연관관계 매핑은 완료
- 양방향 매핑은 반대 방향으로 조회(객체 그래프 탐색) 기능이 추가된 것 뿐
- JPQL 에서 역방향으로 탐색할 일이 많음 (이 경우에만 추가)
- 단방향 매핑을 잘하고 양방향은 필요할 때 추가해도 된다. (테이블에 영향을 주지 않기 때문에)
참조
- 해당 게시글은 김영한님의 "자바 ORM 표준 JPA 프로그래밍 - 기본편" 을 바탕으로 작성되었습니다.
댓글