김영한님이 지음, [자바 ORM 표준 JPA 프로그래밍] 책을 읽고 정리한 필기입니다.📢
연관관계의 주인
객체와 데이터베이스의 패러다임 불일치의 문제
- 객체에는 양방향 연관관계란 존재하지 않음
- 데이터베이스는 외래키를 사용하면 양방향 연관관계가 성립
엔티티를 양방향 연관관계로 설정하면 객체의 참조는 둘인데 외래 키는 하나이기 때문에 둘 사이에 차이가 발생한다.
연관관계 주인 : 위와 같은 이유로 두 객체 연관관계 중 하나를 정해 테이블의 외래키 관리 권한을 부여하는 것
양방향 매핑의 규칙: 연관관계의 주인
- 연관관계 주인
- 데이터베이스 연관관계와 매핑되고 키를 관리(등록, 수정, 삭제)할 수 있음
- 주인 쪽에는
mappedBy
속성을 사용하지 않음
- 주인이 아닌 쪽
- 읽기만 가능
- 주인이 아닌 쪽에서
mappedBy
속성을 사용하여 연관관계의 주인을 지정
※ 연관관계의 주인을 정한다는 것 == 외래 키 관리자를 선택하는 것
연관관계의 주인은 외래키가 있는 곳
연관관계의 주인과 반대편
1
2
3
4
5
6
class Team{
@OneToMany(mappedBy="team") //MappedBy 속성의 값은
//연관관계의 주인인 Member.team
private List<Member> members = new ArrayList<Member>();
...
}
회원 테이블이 외래 키를 가지고 있으므로 Member.team
이 주인
→ Team.members
에는 mappedBy="team"
속성을 사용해 주인이 아님을 명시
(mappedBy
의 값으로 사용된 team
은 연과관계의 주인인 Member
엔티티의 team
필드를 의미)
Tip. 💡
데이터베이스 테이블의 다대일, 일대다 관계에서는 항상 다 쪽이 외래 키를 가진다. 다 쪽인
@ManyToOne
은 항상 연관관계의 주인이 되므로mappedBy
를 설정할 수 없다. 따라서@ManyToOne
에는mappedBy
속성이 없다.
양방향 연관관계 저장
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void testSave(EntityManager em){
//팀1 저장
Team team1 = new Team("team1", "팀1");
em.persist(team1);
//회원1 저장
Member member1 = new Member("member1", "회원1");
member1.setTeam(team1); //연관관계 설정 member1 -> team1
em.persist(member1);
//회원2 저장
Member member2 = new Member("member2", "회원2");
member2.setTeam(team1); //연관관계 설정 member2 -> team1
em.persist(member2);
}
주인이 아닌 방향의 값은 설정하지 않아도 데이터베이스에 외래 키 값이 정상 입력 된다.
MEMBER 테이블 조회 결과
MEMBER_ID | USERNAME | TEAM_ID |
---|---|---|
member1 | 회원1 | team1 |
member2 | 회원2 | team2 |
Team.members
는 연간관계의 주인이 아니기 때문에, 주인이 아닌 곳에서 입력된 아래 코드는 무시된다.
1
2
team1.getMembers().add(member1); //무시(연관관계의 주인이 아님)
team1.getMembers().add(member2); //무시(연관관계의 주인이 아님)
Member.team
은 연관관계의 주인이다. 엔티티 매니저는 아래 코드로 외래 키를 관리 한다.
1
2
member1.setTeam(team1); //연관관계 설정(연관관계의 주인)
member2.setTeam(team2); //연관관계 설정(연관관계의 주인)
댓글남기기