@JoinColumn은 다대일 또는 일대다 연관관계를 매핑할 때 사용한다.
아래의 Member 클래스와 Order 클래스를 살펴보자.
@Entity
@Getter
@Setter
public class Member {
@Id @GeneratedValue
@Column(name="member_id")
private Long id;
@OneToMany(mappedBy = "member")
private List<Order> orders = new ArrayList<>();
}
@Entity
@Table(name="orders")
@Getter
@Setter
public class Order {
@Id @GeneratedValue
@Column(name="order_id")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="member_id")
private Member member;
}
사람 한명은 여러 개의 주문을 할 수 있기 때문에 위처럼 클래스를 생성했다.
@JoinColumn의 name 속성
처음에 나도 헷갈렸던 부분인데 Order 클래스의 member 필드에 붙은 @JoinColumn(name = "member_id")은 Member 클래스의 id 필드에서 설정한 @Column(name = "member_id")을 가리키는게 아니다.
@JoinColumn에서의 "member_id"의 의미는 DB에서 orders 테이블의 외래키 컬럼을 의미한다.
만약 @JoinColumn의 name 속성을 "member_id" -> "member_haha"로 설정한다면 DB에서 orders 테이블 생성 시 외래키 컬럼명이 "member_haha"로 생성된다.
mappedBy
mappedBy는 연관 관계의 주인이 아닌 반대편에서 사용을 해야 한다.
연관 관계의 주인이란 '외래키를 가진 엔티티'이다.
Member 클래스와 Order 클래스는 1 : N 구조이므로 Order 클래스는 Member 클래스의 PK(member_id)를 갖게 된다.
즉, 외래키를 갖게 되므로 연관 관계의 주인은 Order 클래스임을 알 수 있다.
따라서 연관 관계의 주인이 아닌 Member 클래스의 orders 필드에 mappedBy 속성을 사용했다.
@JoinColum의 referenceColumnName 속성
음.. Member 클래스에서는 mappedBy로 orders 필드가 member와 연관 관계를 가진다는 것을 알 수 있다.
그렇다면 그 반대인 Order 클래스의 member 필드는 어떻게 Member 클래스의 orders와 연관 관계를 가진다는걸 알 수 있을까?
@JoinColumn의 referenceColumnName 속성으로 인해 후자도 알 수 있다.
기본적으로 referenceColumnName 속성을 생략하면 대상 테이블의 PK 값으로 설정한다.
이번 예제도 생략된 케이스이다.