@joinColumn의 name속성 이해하기

HwangBaco·2023년 5월 1일
0

질문 : @JoinColumn의 name 속성은 매핑 칼럼 이름과 동일해야 한다?


우리가 JPA 등의 ORM을 사용하기 위해서는, 엔티티 모델링을 하죠. 이 때, DB의 FK와 같은 연관관계를 객체지향적으로 설계할 때 @ManyToOne과 같은 연관관계 어노테이션을 붙이게 됩니다.

이와 같이 종종 따라다니는 어노테이션이 @JoinColumn입니다. 여기서 저는, 강의를 들으면서 너무도 자연스럽게 오해하고 있던 것이 있었습니다.

@Entity
public class Member {

    @Id @GeneratedValue
    @Column(name="member_id")
    private Long id;

    @NotEmpty
    private String name;
    
    @Embedded
    private Address address;

    @OneToMany(mappedBy = "member")
    private List<Order> orders = new ArrayList<>();
}
@Entity
public class Order {

    @Id @GeneratedValue
    @Column(name="order_id")
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="member_id")
    private Member member;

    @OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
    private List<OrderItem> orderItems = new ArrayList<>();


    @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name="delivery_id")
    private Delivery delivery;

    private LocalDateTime orderDate;

    @Enumerated(EnumType.STRING)
    private OrderStatus status;
}

위의 Member와 Order는 일대다(1:N) 관계입니다.

이러한 연관관계에서 외래 키는 일반적으로 '다' 쪽인 Order 테이블에 존재할 것이며, 따라서 외래 키를 가진 Order가 연관관계의 주인일 것입니다.

그렇다면 당연히 'mappedBy' 옵션은 Member 엔티티에 설정해주게 되죠.

저는 여기서 @JoinColumn을 이용하여 기입하는 name 속성을 통해 연관관계가 있는 상대 엔티티(Member)의 id필드 이름(member_id)과 반드시 동일하게 명시하여 묶이는 필드임을 JPA에 알려주는 역할로 이해하고 있었습니다.

결론 : 전혀 그렇지 않다.


하지만 결론은, 엔티티를 DB에 반영할 때 Order 테이블의 칼럼 이름을 설정하는 것이었습니다.

알고 난 후에 생각해보니, DB에 넣을 때에는 Member 객체를 넣을 수 없으니 당연히 연관관계 엔티티의 어떤 값(usu. id값)으로 들어가긴 할텐데, 그 이름을 대개의 경우 재 설정해줘야 하며, 연관관계를 설정함과 동시에 굳이 @Column(name=...)을 설정할 수고를 덜어주는 역할로 사용되는 속성이었습니다.

그렇다면 어떻게 Order 엔티티는 Member 엔티티의 어떤 값을 칼럼 값으로 넣을지 아는걸까요? Member의 입장에서 mappedBy를 선언하여 분명 상대 엔티티(Order)에 자신이 어떤 필드명으로 연관관계가 설정되고 저장되는지 명시하는 것이니 이를 통해 알려준다 치지만, Order엔티티는 어떻게 Member엔티티의 id값을 FK칼럼 값으로 설정하는 걸까요?

@JoinColumn에는 referencedColumnName 속성이 있으며, 이의 default값은 연관된 엔티티의 pk값입니다.

>>> @JoinColumn의 attributes

>>> @Columnd의 attributes : 위 JoinColumn과 상당히 유사함을 확인할 수 있다.

따라서 굳이 설정해주지 않으면 해당 필드의 값이 연관관계가 설정된 상대 엔티티의 pk로 자동 설정되는 것이죠. 대개의 경우 이렇게 사용하니 기본값으로 지정하고 사용하면 됩니다.

이는 상대 엔티티의 @Id가 붙은 필드를 자동으로 지정하니, private Long id;로 선언했든, private Long member_id로 선언했든 신경쓰지 않아도 됩니다.

profile
알고리즘 풀이 아카이브

0개의 댓글