미운 오리 새끼의 우아한 개발자되기

[JPA] 연관관계 매핑 기초 (2) 양방향 연관관계 본문

Spring & Spring Boot/Spring

[JPA] 연관관계 매핑 기초 (2) 양방향 연관관계

Serina_Heo 2023. 4. 9. 16:46

1. 양방향 연관관계

양방향 연관관계란 다음과 같다

  • 회원 -> 팀
  • 팀 -> 회원

2. 양방향 연관관계의 매핑

@Entity
public class Member {
	
    @Id
    @Column(name = "MEMBER_ID")
    private Long id;
    
    private String username;
    
    // 연관관계 매핑
    @ManyToOne // 다(Member)대일(Team)
    @JoinColumn(name = "TEAM_ID") // 외래키를 매핑할 때 쓰는 annotation. 매핑할 외래키 이름을 씀
    private Team team;
    
    // 연관관계 설정
    public void setTeam(Team team) {
    	this.team = team;
    }
    
    // Getter, Setter...

}
@Entity
public class Team {
	
    @Id
    @Column(name = "TEAM_ID")
    private Long id;
    
    private String name;
    
    // 연관관계 매핑
    @OneToMany(mappedBy = "team") // 일(Team)대다(Member)
    private List<Member> members = new ArrayList<>();
    
    // Getter, Setter...

}

mappedBy 속성은 양방향 매핑을 때 사용하는데 반대쪽 매핑의 필드명을 값으로 주면 된다.

사실 객체에는 양방향이라는 것이 없음. 테이블의 경우에는 FK 하나로 두 테이블이 서로 조인해서 사용 가능하니 양방향이지만, 객체의 경우에는 단방향 2개로 양방향인것 처럼 구현하는 것임. 

근데 이렇게 단방향 2개를 사용(즉 양방향)하면, 회원 -> 팀, 팀-> 회원으로 두 곳에서 서로를 참조하므로 관리 포인트가 2개로 늘어나버림.

테이블의 경우에는 FK 하나만 관리하면 되는데..

이런 차이로 인해 JPA 에서는 두 객체 연관관계 중 하나를 정해 테이블의 FK 를 관리하게 하는데 이것을 연관관계의 주인(Owner)라고 함.

 

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

양방향 연관관계 매핑 시 두 연관관계 중 하나를 주인으로 정해야만 함.

이 주인만이 외래키를 관리(등록, 수정, 삭제)할 수 있고 주인이 아닌 쪽은 읽기만 가능.

누가 주인인지 아닌지를 mappedBy 속성으로 나타내는 것.

  • 주인은 mappedBy 속성을 사용하지 않는다.
  • 주인이 아니면 mappedBy 속성을 사용해서 속성의 값으로 연관관계의 주인을 지정해야한다.

주인을 정한다는 것은 사실 FK 관리자를 선택하는 것이다.

 

4. 양방향 연관관계의 주의점

연관관계의 주인만이 외래키의 값을 변경할 수 있다.

즉, Member 객체를 통해서만 필드의 값을 변경할 수 있고, Team 객체를 통해 member 의 값을 변경할 수는 없다. 

-> 양방향이라면서..? 

-> 고로, 양방향 연관관계는 양쪽 다 신경 써야한다. 양방향이 깨지지 않도록! 

아래와 같이 양방향이 깨지지 않도록 구현을 해줘야함.

관계형 DB 에서는 FK 하나로 해결하지만, 객체에서 양방향 연관관계를 사용하려면 로직을 견고히 작성해야함. 

	public void setTeam(Team team) {
	
        // 기존 팀과의 관계 제거
        if (this.team != null) {
            this.team.getmembers().remove(this);
        }
        this.team = team;
        team.getMembers().add(this();

    }

 

5. 정리

  • 단방향 매핑 만으로 테이블과 객체의 연관관계 매핑을 이미 완료됨.
  • 단방향을 양방향으로 만들면 반대방향으로 객체 그래프 탐색 기능이 추가됨.
  • 양방향 연관관계를 매핑하려면 객체에서 양쪽 방향을 모두 관리해야함.

 

연관관계 주인을 정하는 기준은 비즈니스 중요도를 배제하고 단순히 FK 관리자 정도의 의미만 부여해야함.

 

Reference : 자바 ORM 표준 JPA 프로그래밍 (김영한 저)