Spring Data JPA

[JPA] 양방향 연관관계와 연관관계의 주인 - 1 - 경험을 기록하는

여행하는 개발자(SOO) 2024. 6. 16. 21:09
728x90

이전 포스팅의 단방향 연관관계에서 더 발전시켜서 양방향으로 만들어보겠습니다.

모든 코드는 Github에 올라와 있습니다.

양방향 연관관계

두 엔티티가 서로를 참조하는 관계

 

회원과 팀 예시

  • 회원과 팀이 있다.
  • 회원은 하나의 팀에 소속된다.
  • 하나의 팀은 여러 회원을 가지고 있다.

Member와 Team을 양방향 연관관계로 만들어도 DB입장에서는 Table 변화가 없습니다.

DB에서는 Foreign Key를 가지고 Join 해서 데이터를 가지고 오기 때문에 A, B 테이블 상관없이 한쪽에만 Foreing Key가 있으면 됩니다.

객체 연관관계 그림

Member
Member 엔티티는 단방향 연관관계 와 차이가 없습니다.

...
@Entity  
public class Member {  

@Id  
@GeneratedValue(strategy = GenerationType.AUTO)  
@Column(name = "MEMBER_ID")  
private Long id;  

@Column(name = "USERNAME")  
private String username;  

@ManyToOne(fetch = FetchType.LAZY)  
@JoinColumn(name = "TEAM_ID")  
private Team team;  

...
}

 

Team
양방향 연관관계를 만들기 위해서 Team 에서 memberList형태로 가지고 있습니다.

...  
@Entity  
public class Team {  

@Id  
@GeneratedValue(strategy = GenerationType.AUTO)  
@Column(name = "TEAM_ID")  
private Long id;  
private String name;  

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

mappedBy: 양방향 연관관계를 설정할 때, 두 엔티티 간의 관계에서 주인(owner)과 종속(inverse) 관계를 정의

  • 주인(Owner): 외래 키(FK)를 관리하는 쪽 @ManyToOne또는 @JoinColumn을 사용한다.(Member 엔티티에 있는 Team team)
  • 종속(Inverse): mappedBy 속성을 통해 주인을 가리킵니다. 주로 @OneToMany에서 사용한다.(Team 엔티티에 있는 List<Member> members)

JpaMain

위 코드를 보면 em.findmember를 찾고 findMember에서 team으로 갔다가 team에서 member를 조회한 것을 보실 수 있습니다.

단방향 연관관계 에서는 Team에서 Member를 조회할 수 없었지만 TeamMember를 양방향으로 매핑을 하면 Team에서 Member를 조회할 수 있습니다.

양방향 연관관계 데이터 관리는 누가 하나?

결론부터 말하자면, 양방향 연관관계에서 데이터의 수정, 삭제 등 관리는 연관관계 "주인"이 한다.

그럼 1:다 관계에서 누가 주인을 해야 하는가? 그건 바로 '다' 쪽에서 주인을 하고 데이터를 관리해야 한다.

'다' 쪽에서 주인을 하고 데이터를 관리하는 이유는 여러 가지가 있겠지만

  • 데이터베이스 설계 원칙
  • 성능 및 데이터 무결성
  • JPA 구현체의 매핑 전략

등이 있습니다.

데이터베이스 설계 원칙

정규화 원칙에서는 외래키는 종속 관계를 가지는 테이블(Member)에 위치하는 것이 바람직합니다. 관계에서 M쪽(자식 테이블)이 1쪽(부모 테이블)을 참조하게 됩니다.

성능 및 데이터 무결성

성능 효율성: M쪽에 외래 키가 위치한 경우, 데이터 조회와 조인 연산이 효율적입니다.

  • 예) 특정 Team에 속한 모든 Member를 조회할 때 Member 테이블의 team_id 컬럼에 인덱스를 설정하여 빠르게 검색할 수 있습니다.

JPA 구현체의 매핑 전략

JPA에서는 @ManyToOne 관계가 기본적으로 외래 키를 관리하는 주체가 됩니다.(위 예제에서는 Member EntityTeam team)

정리

양방향 연관관계에는 주인과 종속이 있고 주인(Member 엔티티의 Team team)은 데이터를 관리한다.

종속 관계(Team 엔티티의 List<Member> members)에는 mappedBy로 주인을 가리키고 조회의 역할을 한다.
주인은 항상 1:다 관계에서 다(Member)가 된다.

728x90