JPA @JoinColumn
@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;
}
- 위의 두 엔티티를 보면 Member와 Order는 일대다(1:M) 관계이다.
- 그러면 외래키는 DB설계상
다
쪽인 Order에 존재한다. - 외래키가 존재하는 Order가 연관관계의 주인이 된다.
- 이때, 양방향 매핑이므로 주인이 아닌 Member엔티티에 mappedBy 옵션을 설정하여 Order엔티티의 member 참조로 테이블에 매핑되는 것을 알려야 한다.
- 연관관계의 주인인 Order에서는 @JoinColumn을 설정해야 한다.
여기서 헷갈렷던 점은 @JoinColumn 이름의 역할이었다.
나는 이미 DB의 Orders 테이블에 member_id라는 필드가 존재하고,
이 외래키 필드와 Order 엔티티 member참조와 매핑하는 것으로 이해했기 때문이다.
하지만 그게 아니라, name(이름) 속성은 말 그대로 테이블의 컬럼명을 설정하는 것이다. 즉 @JoinColumn("member_id")로 설정하면 ORDERS 테이블에 member_id 필드가 추가 되고, @JoinColumn("order_member_id")로 설정하면 order_member_id 필드가 추가된다.
name 속성은 단순히 테이블의 필드명을 정의하는 것이다.
그렇다면 Order엔티티는 Member와 연관관계를 맺는 다는 것을 어떻게 알 수 있을까?
Member엔티티는 mappedBy를 통해서 연관관계를 알려주고 있는데 말이다.
바로 referencedColumnName이라는 속성을 이용하면 된다.
해당 속성에는 여러가지 내용이 있지만,
간략하게 설명해서 해당 속성을 생략하면 자동으로 대상 테이블의 PK 값으로 지정된다.
즉 우리는 속성을 생략했으므로, member테이블의 PK인 member_id가 자동으로 참조하는 컬럼이 되는 것이다. 따라서 @JoinCoulumn("member_id")에서 member_id 와 MEMBER 테이블의 member_id가 매핑되고 mappedBy 속성이 없는 Order엔티티가 연과관계의 주인으로 설정되는 것이다.
Order클래스와 ORDERS 테이블을 매핑해주는것은 @Entity 어노테이션이다.
여기서 Order클래스가 가지고 있는 member 참조를 DB 테이블상에서 설계할수 없는데 JPA가 중간에서 referencedColumnName 속성을 보고 상대 테이블의 Pk로 자동 매핑해주어서 객체의 참조와 외래키의 매핑이 성립된다.
'JPA > JPA Basic' 카테고리의 다른 글
[JPA] 8. 값 타입 (0) | 2023.01.31 |
---|---|
[JPA] 7. 프록시와 연관관계 관리 (0) | 2023.01.31 |
[JPA] 6. 고급 매핑 (0) | 2023.01.29 |
[JPA] 5. 다양한 연관관계 매핑 (0) | 2023.01.29 |
[JPA] 참고. Entity, DAO, DTO, VO (0) | 2023.01.27 |
[JPA] 에러. SQL Error 23505 (0) | 2023.01.27 |
[JPA] 4. 연관관계 매핑 기초 (0) | 2023.01.27 |
[JPA] 3. 엔티티 매핑 (0) | 2023.01.26 |