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

다대일

  • 다대일 관계의 반대 방향은 항상 일대다, 일대다 관계의 반대 방향은 항상 다대일
  • 데이터베이스 테이블의 일(1), 다(N) 관계에서 외래 키는 항상 ‘다’쪽에 있음
  • 객체 양방향 관계에서 연관관계의 주인은 항상 ‘다’쪽이어야 함

다대일 단방향[N:1]

여러 회원이 하나의 팀을 참조하고, 회원들은 팀을 참조하지만 반대로 팀은 회원을 참조하지 않는 경우 : 다대일 관계

img-name
다대일 단방향

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Entity
public class Member{
    @Id @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;

    private String username;

    @ManyToOne
    @JoinColumn(name = "TEAM_ID")
    private Team team;

    //Getter, Setter ...
    ...
}
1
2
3
4
5
6
7
8
9
10
11
@Entity
public class Team{
    @Id @GeneratedValue
    @Column(name = "TEAM_ID")
    private Long id;

    private String name;

    //Getter, Setter ...
    ...
}

다대일 양방향[N:1, 1:N]

img-name
다대일 양방향

  • 실선이 연관관계의 주인(Member.team)이고 점선(Team.members)은 연관관계의 주인이 아니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Entity
public class Member {
    @Id @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;

    private String username;

    @ManyToOne
    @JoinColumn(name= "TEAM_ID")
    private Team team;

    public void setTeam(Team team) {
        this.team = team;

        //무한루프에 빠지지 않도록 체크
        if(!team.getMembers().contains(this)){
            team.getMembers().add(this);
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Entity
public class Team {
    @Id @GeneratedValue
    @Column(name = "TEAM_ID")
    private Long id;

    private String name;

    @OneToMany(mappedBy = "team")
    private List<Member> members = new ArrayList<Member>();

    public void addMember(Member member) {
        this.members.add(member);
        if(member.getTeam() != this) { //무한루프에 빠지지 않도록 체크
            member.setTeam(this);
        }
    }
}

양방향은 외래 키가 있는 쪽이 연관관계의 주인이다.

  • 일대다와 대대일 연관관계는 항상 다(N)에 외래 키가 있다.
  • 다쪽인 MEMBER 테이블이 외래 키를 가지고 있으므로 Member.team이 연관관계의 주인이다.
  • JPA는 외래키를 관리할 떄 연관관계의 주인만 사용한다.
  • 주인이 아닌 Team.members는 조회를 위한 JPQL이나 객체 그래프를 탐색할 때 사용한다.

양방향 연관관계는 항상 서로를 참조해야 한다.

  • 어느 한 쪽만 참조하면 양방향 연관관계가 성립되지 않는다.
  • 항상 서로 참조하게 하려면? 연관관계 편의 메소드를 작성한다. (setTeam(), addMember())
  • 편의 메소드는 한 곳에만 작성하거나 양쪽 다 작성할 수 있는데, 양쪽에 다 작성 시 무한루프에 빠지므로 주의해야 한다.

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

댓글남기기