[JPA] 연관관계

종원유·2022년 7월 11일
0

JPA

목록 보기
1/2

이번 포스트는 JPA에서 연관관계의 주인 개념에 대해 정리하는 포스트이다.

연관관계의 주인에 대해 설명하기 앞서, 먼저 연관관계에 대해서 설명하고자 한다.

연관관계

연관 관계를 매핑할 때, 생각해야할 것은 크게 3가지이다.
방향 : 단방향, 양방향
연관 관계의 주인 : 양방향일 때, 연관 관계에서 관리 주체
다중성 : 다대일(N:1), 일대다(1:N), 일대일(1:1), 다대다(N:M)

방향

데이터베이스 테이블은 외래 키 하나로 양 쪽 테이블 조인이 가능하다.
따라서 데이터베이스는 단방향, 양방향 나눌 필요가 없다(방향의 개념이 없음, 쌍방의 데이터를 알 수 있기 때문).
그러나 객체는 참조용 필드가 있는 객체만 다른 객체를 참조하는 것이 가능하다.
그렇기에 두 객체 사이에 하나의 객체만 참조용 필드를 갖고 참조하면 단방향 관계, 두 객체 모두가
각각 참조용 필드를 갖고 참조하면 양방향 관계라고 한다.
하지만 엄밀히 얘기하면, 양방향 관계는 없고 두 객체가 단방향 참조를 각각 가져서 양방향 관계처럼 사용하는 것을 말하는 것이다.

@EnTity
class Member{
	@Id @GeneratedValue
    @Column(name = "MEMBER_ID")
	private Long id;
    
    @ManyToOne
    @JoinColumn(name = "TEAM_ID")
    private Team team;
}
@EnTity
class Team{
	@Id @GeneratedValue
    @Column(name = "TEAM_ID")
	private Long id;
    @OneToMany(mappedBy = "team")
    private List<Member> members;
}
Member findMember = em.find(Member.class, memberId);
List<Member> members = findMember.getTeam().getMembers();

findMember.getTeam().getMembers(); 한 번에 가져오는 것이 아닌, team -> member
단방향 -> 단방향
이렇게 Member는 Team을 참조하고, Team은 Member를 참조한다면 양방향 연관관계가 된다.

하지만, 객체 입장에서 양방향 매핑을 했을 때 오히려 복잡해질 수 있다.
우리가 접하는 일반적인 비즈니스 애플리케이션에서 사용자(User) 엔티티는 하나의 엔티티가 굉장히 많은 엔티티와 연관 관계를 갖는다.
이런 경우에 양방향 관계가 여럿 있다면 사용자 엔티티는 수많은 테이블과 연관관계를 맺고 엔티티를 조회할 때, 수 많은 불필요한 쿼리들이 실행될 것이기 때문이다.
그렇기에 기본적으로는 단방향 매핑으로 사용하고 추후 역방향으로 객체 탐색이 꼭 필요한 경우에만 추가하는 것이 좋다.

연관관계의 주인

두 객체(Member, Team)가 양방향 관계(Member -> Team(단방향), Team -> Member(단방향))를 맺을 때 연관관계의 주인을 정해야 한다.
연관 관계의 주인을 지정하는 것은 두 단방향 관계에서 제어의 권한을 갖는 관계의 주인이 어떤 것인지 JPA에게 명시하는 것이다.
연관관계의 주인은 연관 관계를 갖는 두 객체 사이에서 조회, 저장, 수정, 삭제를 할 수 있지만, 연관관계의 주인이 아니면 조회만 가능하다(값을 변경하여도 반영되지 않음).
연관관계의 주인이 아닌 객체는 mappedBy 속성으로 주인을 지정해야 한다.

외래 키가 있는 객체를 연관 관계의 주인으로 지정한다. 다대일 관계에서 다에 해당하는 객체

Why ?

MemberTeam
MEMBER_ID(PK)
TEAM_ID(FK)
...
TEAM_ID(PK)
...

위처럼 Member와 Team 테이블이 있을 때, Member테이블의 경우 MEMBER_ID와 TEAM_ID(FK)를 가지고 있어 TEAM의 참조 값도 가지고 있지만, Team 테이블의 경우 TEAM_ID(PK)만 가지고 있으므로 관계의 주인은 Member가 된다.

연관관계의 주인을 Why?

Member와 Team이 양방향 연관관계를 가질 때, Member의 이름을 수정해야 한다고 가정하자.
이 때 Member의 name을 수정할지 Team의 Member의 name을 수정할 지, JPA의 입장에서는 관리할 포인트가 두 개로 나뉘므로 어디를 수정할지 혼란을 주게된다.
그렇기 때문에 두 객체 사이의 연관관계의 주인을 정해서 명확하게 관계의 주인을 정하는 것이다.

참조 : https://jeong-pro.tistory.com/231

profile
개발자 호소인

0개의 댓글