[JPA] 단방향 연관관계와 양방향 연관관계

HAEN·2023년 1월 6일
0

JPA

목록 보기
2/5

1. 연관관계가 필요한 이유

  • DB의 테이블은 외래 키로 조인을 사용하여 연관된 테이블을 찾음
  • 객체는 참조를 사용해서 연관된 객체를 찾음
    => 테이블과 객체 사이에 큰 간격 존재, 따라서 연관관계를 설정하여 간격을 없앰

2. 단방향 연관관계


객체 연관관계에서 Member는 Team을 참조하지만, Team은 Member를 참조하지 않음
이처럼 연관관계에서 하나의 객체만 다른 객체를 참조할 때 이를 '단방향 연관관계'라고 함
MEMBER 테이블은 TEAM 테이블의 기본키를 외래키로 사용하여 조인함

// Member 객체
@Entity
public class Member {
	@Id @GeneratedValue
    @Colum(name = "member_id")
    private Long id;
    
    @ManyToOne // 연관관계 설정
    @JoinColum(name = "team_id") // 조인할 때 컬럼명 설정
    private Team team;
    
    private String username;
 } 
// Team 객체
@Entity
public class Team {
	@Id @GeneratedValue
    @Colum(name = "team_id")
    private Long id;

    private String name;
 } 
Team team = new Team();
em.persist(team);

Member member = new Member();
member.setTeam(team);  // 단방향 연관관계 설정, 참조 저장
em.persist(member);

Team findTeam = em.find(Team.class, member.getTeam()); // 참조를 사용해서 연관관계 조회

Team newTeam = new Team();
em.persist(newTeam);
member.setTeam(newTeam); // member의 팀 변경

3. 양방향 연관관계


객체 연관관계에서 Member는 Team을 참조하고 Team 또한 Member를 참조함
이처럼 연관관계에서 두 객체 모두 서로를 참조하는 것을 '양방향 연관관계'라고 함
하지만 테이블 연관관계에서는 MEMBER 테이블에만 외래키가 존재

객체의 양방향 연관관계: 객체의 양방향 관계는 사실 서로 다른 단방향 관계 2개, 따라서 객체를 양방향으로 참조하려면 단방향 연관관계를 2개 만들어야 함
테이블의 양방향 연관관계: 테이블은 외래 키 하나로 두 테이블의 연관관계를 관리함(양쪽으로 조인 가능)

이러한 차이점으로 인해 양방향 매핑을 할 때 연관관계의 주인만이 외래키를 관리해야함
연관관계의 주인은 외래키가 있는 객체
연관관계의 주인이 아닌 객체는 mappedBy 속성으로 주인을 지정해야함

// Member 객체(단방향과 동일)
@Entity
public class Member {
	@Id @GeneratedValue
    @Colum(name = "member_id")
    private Long id;
    
    @ManyToOne // 연관관계 설정
    @JoinColum(name = "team_id") // 조인할 때 컬럼명 설정
    private Team team;
    
    private String username;
 } 
// Team 객체
@Entity
public class Team {
	@Id @GeneratedValue
    @Colum(name = "team_id")
    private Long id;

    private String name;
    
    @OneToMany(mappedBy = "team") // 추가 mappedBy로 연관관계의 주인이 아님을 나타냄
    private List<Member> members = new ArrayList<>();
 } 
Team team = new Team();
em.persist(team);

Member member = new Member();
member.setTeam(team);  // 양방향 매핑시 연관관계 주인에 값을 입력해야함
team.getMembers().add(member); // 하지만순수한 객체관계를 고려하여 항상 양쪽 다 값을 입력하는 것을 원칙으로 함
em.persist(member);

연관관계 편의 메서드를 통해 값을 입력할 수 있음(둘 중 하나 선택)

// Member 엔티티에 추가
public void changeTeam(Team team) {
	this.team = team;
    team.getMembers().add(this);
}

// Team 엔티티에 추가
public void addMember(Member member) {
    member.setTeam(this);
	members.add(member);
}



참고: 인프런 자바 ORM 표준 JPA 프로그래밍 기본편 - 김영한
profile
핸수

0개의 댓글