[JPA] 연관관계 편의 메서드

Woolly·2023년 5월 17일
0
    //== 연관관계 메서드 ==//
    public void setMember(Member member) {
        this.member = member;
        member.getOrders().add(this);
    }

    public void addOrderItem(OrderItem orderItem) {
        orderItems.add(orderItem);
        orderItem.setOrder(this);

    }

    public void setDelivery(Delivery delivery) {
        this.delivery = delivery;
        delivery.setOrder(this);
    }

연관관계 편의 메서드: 양방향 연관관계를 한번에 설정하는 편리한 메서드

질문이 엔티티 A와 B가 서로 양방향 연관관계인데, 어디에 연관관계 편의 메서드를 두는게 좋은가?로 이해했습니다.

우선 3가지 선택지가 있습니다.

  • 엔티티 A에 둔다.

  • 엔티티 B에 둔다.

  • 엔티티 A,B에 둘다 둔다.

둘다 두는 것은 혼란을 가중하기 때문에 제외하고, A, B중 하나를 선택해서 사용하는 것이 좋다 생각합니다. 그러면 여기서 A,B 중에 하나를 선택해야 하는데 사실 이 부분이 고민하셨던 것 처럼 정답이 없습니다. 이 부분은 JPA의 영역이라기 보다는 오히려 객체지향 설계의 영역이기 때문입니다.

예를 들어서 Order와 Delivery 중에서 우리팀의 핵심 비즈니스가 주문이라면 Order에 연관관계 편의 메서드를 두는 것이 더 나은 선택일 확율이 높습니다. 그런데 만약 우리팀이 배달을 책임지는 팀이고 Order엔티티는 있지만, 관련된 정보는 크게 의미가 없다면 Delivery를 중심으로 비즈니스 로직이 진행되므로, Delivery가 중심 엔티티가 되기 때문에 Delivery에 연관관계 편의 메서드를 두는 것이 나은 선택이 됩니다.

도메인 주도 설계(DDD)에 나오는 Aggregate Root라는 개념을 사용한다면, Aggregate Root에 연관관계 편의 메서드를 두는 것이 좋은 선택일 확율이 높습니다.

조언들 드리자면, 실제 엔티티를 사용하는 비즈니스 로직을 구현을 하실 때, A에 연관관계 편의 메서드를 두고 개발을 해보고, 바꾸어서 B에 연관관계 편의 메서드를 두어 보면, 어디에 두는 것이 더 유지보수 하기 쉬운지 바로 보이실 꺼에요. 이게 뭔가 엔티티 만으로는 잘 안보이고, 실제 비즈니스 로직과 함께 있을 때는 어디에 두는 것이 좋은지 바로 보이더라구요. (서비스 계층에서 코드가 몇줄 줄어들고, 쉽게 이해되고 등등) 생각해보니 저도 엔티티를 설계할 때는 A라고 했다고, 중간에 실제 비즈니스 로직을 보고 B로 리펙토링 한 경우도 있었습니다^^


출처 : https://www.inflearn.com/questions/16308/%EC%97%B0%EA%B4%80%EA%B4%80%EA%B3%84-%ED%8E%B8%EC%9D%98-%EB%A9%94%EC%84%9C%EB%93%9C%EC%97%90-%EA%B4%80%EB%A0%A8-%EB%AC%B8%EC%9D%98


++)

1)

연관관계 편의 메서드는 애플리케이션 로직을 개발하면서 보통 좀 더 주도적인 곳이 있는데 이 곳에서 형성하게 됩니다. 예를 들어서 자동차와 바퀴가 있다면 바퀴가 연관관계의 주인이 되는데, 보통 자동차를 중심으로 애플리케이션 로직이 동작하기 때문에 자동차에 연관관계 편의 메서드를 작성하게 됩니다. 이게 상황마다 달라서 정답은 없는데, 연관관계의 주인으로 설정된 곳과는 무관합니다. 비즈니스 중심이 되는 곳이 주로  연관관계 편의 메서드를 사용하게 됩니다.

출처 : https://www.inflearn.com/questions/199084/%EC%96%91%EB%B0%A9%ED%96%A5-%EC%97%B0%EA%B4%80%EA%B4%80%EA%B3%84%EC%97%90%EC%84%9C%EC%9D%98-%ED%8E%B8%EC%9D%98-%EB%A9%94%EC%84%9C%EB%93%9C

2)

양방향이라는 것은 1:N, N:N 보다는 객체가 서로를 참조하고 있는지 여부입니다. (객체그래프 탐색을 상호간에 지원하는가 라고 할수도 있습니다). 가령 Member와 Team 엔터티가 있을 때, Member객체에서 Team 객체로 탐색할 수 있는 방업을 제공하며 동시에 Team에서 Member 객체로 탐색할 수 있는 방법을 제공한다면 이 경우가 양방향 관계입니다.

Order와 Member 사이의 양방향 관계를 설정하기 위해 연관관계 메서드를 사용합니다. member.getOrders().add(this) 코드에서 this는 회원 주문리스트에 현재 주문 인스턴스를 연결한다(추가한다)는 의미의 코드입니다.


출처 :

https://www.inflearn.com/questions/866579/%EC%97%B0%EA%B4%80%EA%B4%80%EA%B3%84-%EB%A7%A4%EC%86%8C%EB%93%9C-%EC%96%91%EB%B0%A9%ED%96%A5-%EA%B4%80%EA%B3%84

3)

Member에서 본인이 주문한 Order에 대해 접근하려면 Order에 대한 참조를 가지고 있어야 합니다. 그 참조가 Member의 orders입니다.

반대로 Order에서 주문자를 찾아가려면 Member에 대한 참조가 있어야 합니다. 그 참조가 Order의 member입니다.

DB상에서는 Order의 foreign key인 Member_id로 member를 찾아갈 수 있지만

객체상에서는 Member에서 order를 찾아갈 방법이 없습니다.

따라서 주문할 때 Member에는 order를, Order에는 member를 넣어줘서 서로 참조할 수 있게 하는 것입니다.


출처 :

https://www.inflearn.com/questions/306416/%EC%96%91%EB%B0%A9%ED%96%A5-%EC%97%B0%EA%B4%80%EA%B4%80%EA%B3%84-%EC%84%A4%EC%A0%95%EC%A7%88%EB%AC%B8

4)

'객체 그래프 탐색' 방향은 단방향 혹은 양방향으로 할 수 있습니다.
(강의 내용에서도 언급하듯 사실 양방향은 단방향+단방향일 뿐입니다)

요구사항이 '회원'을 주문한 후 그와 관련한 '주문'을 조회해야 한다면 다음은 타당해 보입니다. (Member -> Order)

그리고 주문을 조회할 땐 보통 주문자 정보도 같이 조회해야 합니다. 그러니 다음의 그래프 탐색도 타당한합니다. (Order -> Member)

이처럼 요구사항에 따라 객체간의 관계를 단방향 혹은 양방향으로 설정할 수 있습니다.

출처 : https://www.inflearn.com/questions/765601/member-order-%EA%B0%84%EC%97%90-%EC%97%B0%EA%B4%80%EA%B4%80%EA%B3%84%EB%A5%BC-%EC%9E%85%EB%A0%A5%ED%95%A0%EB%95%8C-%EC%99%9C-%EB%91%98%EB%8B%A4-%EC%9E%85%EB%A0%A5%ED%95%B4%EC%A4%98%EC%95%BC-%ED%95%98%EB%82%98%EC%9A%94

profile
Ad Astra

0개의 댓글