김영한님이 지음, [자바 ORM 표준 JPA 프로그래밍] 책을 읽고 정리한 필기입니다.📢

연관관계의 주인

객체와 데이터베이스의 패러다임 불일치의 문제

  • 객체에는 양방향 연관관계란 존재하지 않음
  • 데이터베이스는 외래키를 사용하면 양방향 연관관계가 성립

엔티티를 양방향 연관관계로 설정하면 객체의 참조는 둘인데 외래 키는 하나이기 때문에 둘 사이에 차이가 발생한다.

연관관계 주인 : 위와 같은 이유로 두 객체 연관관계 중 하나를 정해 테이블의 외래키 관리 권한을 부여하는 것

양방향 매핑의 규칙: 연관관계의 주인

  • 연관관계 주인
    • 데이터베이스 연관관계와 매핑되고 키를 관리(등록, 수정, 삭제)할 수 있음
    • 주인 쪽에는 mappedBy속성을 사용하지 않음
  • 주인이 아닌 쪽
    • 읽기만 가능
    • 주인이 아닌 쪽에서 mappedBy 속성을 사용하여 연관관계의 주인을 지정

※ 연관관계의 주인을 정한다는 것 == 외래 키 관리자를 선택하는 것

연관관계의 주인은 외래키가 있는 곳

img-name
연관관계의 주인과 반대편

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); //연관관계 설정(연관관계의 주인)

JPA 카테고리 내 다른 글 보러가기

댓글남기기