김영한님의 인프런 강의와 PDF를 바탕으로 정리하였습니다.
https://www.inflearn.com/courses?s=%EA%B9%80%EC%98%81%ED%95%9C
양팡향 매핑에서 객체와 DB 테이블은 큰 차이가 있습니다.
객체는 서로를 참조하기 위해 양쪽이 서로의 참조를 가지고 있어야 합니다.
이게 말이 양방향 매핑이지 사실 두개의 단방향이 있는 것입니다.
위 그림에서는
멤버->팀 으로 가는 연관관계 하나, 팀->멤버 로 가는 연관관계 하나.
객체 다이어그램에 따라 엔티티를 설계하면 아래와 같습니다.
Team
Team에 members라는 List형 필드가 생겼습니다. 이제 Team에서도 멤버를 조회할 수 있게 되었습니다.
@OneToMany : Team엔티티와 Member엔티티의 관계에서 Team이 1:N 중 1이므로 @OneToMany어노테이션이 필요합니다.
(mappedBy = "team") : 아래 Member클래스에서 private Team team에 매핑되어 있음을 알리기 위해 "team"을 넣습니다. mappedBy에 대한 더 자세한 설명은 아래에서 하겠습니다.
Member
이렇게 설계된 엔티티를 가지고 조회하는 코드를 보면 다음과 같습니다.
코드를 보면 id=4인 멤버를 찾고, 멤버가 속한 팀을 getTeam()으로 뽑아서 다시 그 팀에 속한 멤버들을 List로 뽑고있습니다.
이제 이러한 객체적 코드가 가능해진 것입니다.
하지만
DB테이블은 객체 세상과 달리 하나의 FK로 양방향을 모두 오갈 수 있습니다.
위에서처럼 엔티티 클래스들을 설계하였지만 이렇게 객체와 DB테이블의 차이 때문에 한가지 딜레마가 생기게 됩니다.
멤버의 팀이 바뀌었을 때, 테이블과 매핑 시 Member의 team의 변화로 테이블을 update을 할까?
Team의 members의 변화로 테이블을 update할까?
정답은 "연관관계의 주인을 선택하라" 입니다.
연관관계의 주인이란 현재 테이블상 FK를 가지고 있는 쪽입니다. FK를 가지고 있는 쪽이 연관관계의 주인이 됩니다.
이렇게 연관관계를 설정하는 법을 알았으니, 코드를 다시 보겠습니다.
Member
Team
mappedBy
mappedBy는 연관관계의 주인이 아닌 쪽에 사용합니다. mappped By로 나의 주인을 지정합니다.
즉 현재 members칼럼은 Member테이블의 team에 의해 매핑된. 종속적인 칼럼인 것입니다.
그리하여 members로는 read만 가능하고, write는 불가능해집니다.
members List에 있는 참조값을 꺼내서 아무리 member의 팀을 바꾼다거나 해도, DB에 전혀 반영되지 않으니 주의해야합니다.
아래는 이를 포함한 규칙들입니다.
양방향 매핑 규칙:
1. 객체의 두 관계중 하나를 연관관계의 주인으로 지정
2. 연관관계의 주인만이 외래 키를 관리(등록, 수정)
3. 주인이 아닌 쪽은 읽기만 가능
4. 주인은 mappedBy 속성 사용 X
5. 주인이 아니면 mappedBy 속성으로 주인 지정
외래키가 있는 곳이 무조건 N : 1중 N이 된다. 연관관계의 주인이다. 진짜 매핑이다. 진짜 매핑을 테이블에 매핑하라.
연관관계의 주인에 반드시 값을 입력해야한다! 아래처럼~
하지만(다시 반전) 영속성 컨텍스트를 flush, clear하지 않을 경우 문제가 생길 수 있기 때문에
양방향 매핑시 양방향 모두에 값을 넣어줘야 합니다.
그런데 코드를 작성하다 보면 실수로 양방향 중 하나를 누락할 수 있습니다.
그래서 아래처럼 연관 관계 편의 메서드를 작성해주는 것이 좋습니다.
연관 관계 편의 메서드란 하나의 연관관계 값을 설정해줄 때 나머지도 같이 한번에 설정해 주는 것입니다.
아래는 연관관계 편의 메서드를 사용한 코드입니다.
정리:::
'JPA > JPA원리' 카테고리의 다른 글
13 다대일, 일대다 연관관계 (0) | 2021.07.13 |
---|---|
12 JPA 양방향 연관관계 실전예시 (0) | 2021.07.07 |
10 JPA 단방향 연결관계 (객체적 설계도입) (0) | 2021.07.05 |
9 JPA 요구사항 추가(관계형 DB의존적 설계) (0) | 2021.07.05 |
8 JPA 기본키 매핑 (0) | 2021.07.05 |