패러다임의 불일치
- 테이블은 외래키로 조인을 사용해서 연관된 테이블을 찾는다.
- 객체는 참조를 사용해서 연관된 객체를 찾는다.
1. 양방향 연관관계
단방향 | 양방향 |
패러다임의 불일치
- 테이블은, Foreign Key 한개만 있으면 양쪽으로 모두 조회가 가능하다.
- 객체는 양쪽에 모두 세팅해줘야 양쪽으로 모두 조회가 가능하다.
2. 연관관계 주인과 mappedBy
객체와 테이블이 관계를 맺는 차이
객체 = 연관관계 2개 = 단방향 연관관계 2개
- 회원 -> 팀 연관관계 1개 (단방향)
- 팀 -> 회원 연관관계 1개 (단방향)
테이블 = 연관관계 1개
- 회원 <-> 팀 연관관계 1개만으로, (양방향)을 모두 접근할 수 있음
객체의 양방향 관계는 사실, 서로 다른 단방향 관계 2개이다. | 테이블은 하나의 외래키로, 양방향 연관관계를 할 수 있다. |
연관관계의 주인 (Owner)
연관관계의 주인은 어떻게정할까? (1, 2번의 조건이 있다면) 1. Member 내부에 Team 값이 없고, Team 내부에 members에 Member 가 속해있다면, 그때 데이터베이스에 있는 TEAM_ID 를 갱신해야하는가? 2. Member 내부에 Team 값이 있고, Team 내부에 members에 Member가 속해있지 않다면, 그때 데이터베이스에 있는 TEAM_ID 를 갱신해야하는가? 헷갈린다.. 따라서 룰이 생긴다. - 둘 중 하나로 외래키를 관리해야한다. - 아니면 List members (1번) 로 관리할 것이냐 - team 으로 관리 (2번)할 것이냐, |
따라서, 위의 룰을 기초로
- Member 내부에 있는 team
- Team 내부에 있는 members
중, 어떤 거에 따라서 데이터베이스에 있는 Team_ID(FK) 를 갱신할 것인지 선택해야 한다.
선택이 완료됐다면
- 연관관계의 주인만이 외래키를 등록, 수정, 조회 할 수 있다.
- 주인이 아닌 쪽은 읽기만 가능하다.
- 주인 쪽에는 mappedBy가 없다.
- 주인이 아닌쪽에서 mappedBy 속성을 통해 주인을 지정한다.
그렇다면 선택은 누구로 해야하는가???
- 위의 그림에 기반하면, Member.team 혹은 Team.members 둘 중 누구를 선택해야하는가?
- 외래키가 있는 곳을 주인으로 정해라 (절대적인 것은 아니나 이게 맞다.)
이유는?
- 만약 외래키가 없는 쪽인 Team.members를 주인으로 했다고 해보자.
- Team.members.add(member) 를 하면 Member Table의 FK 가 갱신된다.
- Team.members.remove(member) 를 하면 Member Table 의 FK 가 갱신된다.
- Team 쪽에서 추가를 했는데 Member Table 의 FK 가 변한다?
- 벌써부터 복잡해진다.
- 또한, 성능이슈도 있다.
- 반대로 한다면, Member.Team 을 주인으로 했다면
- Member.add(team) 을 하면 Member Table의 FK 가 갱신된다.
- Member.remove(team) 을 하면 Member Table 의 FK 가 갱신된다.
- Member 쪽에서 변경을 가했고, Member Table 의 FK 가 변하므로
- 이해가기가 좋다.
3. 양방향 연관관계 주의점
1. 순수 객체 상태를 고려해서 항상 양쪽에 값을 설정하자.
- Member.team 을 연관관계의 주인으로 설정했으므로
- Member.setTeam(team) 만 해도, 데이터베이스의 FK 에는 트랜잭션이 커밋된 이후 정상적으로 반영되나
- 객체지향적인 관점에서 team.getMembers.add(member) 를 같이 해주자.
- 자세한 이유는 실제 강의를 참조!
2. 연관관계 편의 메소드를 생성하자
public void changeTeam(Team team) {
this.team = team;
team.getMembers().add(this);
}
3. 양방향 관계에서 무한루프를 조심하자
- toString()
- Json 생성 라이브러리
- 엔터티를 직접 Response로 보내버리는 경우에 생긴다.
- 해결책 : 컨트롤러에서는 엔터티를 절대 반환하지 말아라, Dto로 변환해서 반환해라
4. 팁
단방향 매핑만으로 설계를 끝내라
- 나중에 필요하면 추가하면된다.
- 어차피 데이터베이스 테이블에는 영향 안준다.
'강의 정리 > 자바 ORM 표준 JPA' 카테고리의 다른 글
6. 고급 매핑 (0) | 2020.12.29 |
---|---|
5. 다양한 연관관계 매핑 (0) | 2020.12.28 |
3. 엔티티 매핑 (0) | 2020.12.27 |
2. 영속성 관리 (0) | 2020.12.26 |
1. JPA 시작하기 (0) | 2020.12.26 |