[JPA] 양방향 연관관계

홍건의·2022년 3월 30일
0

JPA 학습

목록 보기
5/11

양방향 매핑은 복잡하다. 우선 단방향 매핑을 사용하고 반대방향으로 객체그래프 탐색 기능이 필요할 때 양방향을 사용하도록 코드를 추가해도 된다.

양방향 관계

public class Member {
	private Long id;
    private Team team;
    private String userName;
}

public class Team {
	private Long id;
    private String name;
    private List<Member> members;
}
  • 회원에서 팀을 조회 시 (Member.team)
  • 팀에서 회원을 조회 시 (Team.members)

위의 클래스 관계가 DB로 넘어오면
Member가 Team 테이블의 기본키를 외래키로 갖고 있다.
외래키 하나만으로 양방향 조회가 가능하므로 처음부터 양방향 관계다.

양방향 연관관계 매핑

이하 멤버(多)

@Entity
public class Member {
	
    @Id
    @Column(name = "MEMBER_ID")
    private String id;
    
    private String username;
    
    @ManyToOne
    @JoinColumn(name = "TEAM_ID")
    private Team team;
    
    public void setTeam(Team team) {
    	this.team = team;
    }

}

이하 팀(1)

@Entity
public class Team {
	
    @Id
    @Column(name = "TEAM_ID")
    private String id;
    
    private String name;
    
    @OneToMany(mappedBy = "team")
    private List<Member> members = new ArrayList<Member>();
    
}

팀과 회원은 일대다 관계다. 따라서 팀 Entity에 List를 추가한다.
일대다 관계를 매핑하기위해 @OneToMany 매핑정보를 사용.

mappedBy는 속성이 양방향 매핑일 때 사용한다. 반대쪽 매핑 필드의 이름 값으로 지정한다.

테이블에서는 외래키 하나로 2개 테이블을 관리한다.
엔티티를 양방향 연관관계로 설정하며 객체의 참조는 둘인데 외래키는 하나다.
따라서 둘 사이에 차이가 발생한다.

이런 차이로 JPA에서는 두 객체 연관관계 중 하나를 정해서 테이블의 외래키를 관리해야 하는데 이것을 연관관계의 주인이라고 한다.

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

양방향 연관관계 매핑 시 지켜야 할 규칙이 있다.
연관관계의 주인만이 DB 연관관계와 매핑되고 외래키를 관리(C/U/D)할 수 있다.
주인이 아닌 쪽은 오로지 읽기(R)만 할 수 있다.

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

연관관계 주인을 정한다는 것은 사실 외래키 관리자선택하는 것이다.

연관관계의 주인테이블에 외래키가 있는 곳으로 정해야 한다.
위 예시에서는 회원 테이블이 외래키를 가지고 있으므로 Member.team이 주인이 된다.
주인이 아닌 Team.members에는 mappedBy="team" 속성을 사용해서 주인이 아님을 설정한다.

2024.06.04 업데이트

@JoinColumn에서 name 필드는 해당 entity에서 외래키 칼럼명을 매핑하는 것이므로 기본키 테이블 필드명이랑 반드시 일치할 필요는 없다

@Entity
@Table(name = "follow_info")
@Getter
public class FollowInfo extends BaseEntity {


    @ManyToOne
    @JoinColumn(name = source_user_id)
    private User srcUser;

    @ManyToOne
    @JoinColumn(name = target_user_id)
    private User targetUser;

}

JoinColumn에 name 속성 값이 같으면 에러 발생함.

profile
Backend Developer

0개의 댓글

관련 채용 정보