[Spring] JPA 연관관계 메서드
A A

연관관계 메서드란?

객체간 연관관계 설정시 사용하는 메서드.

주로 Entity간의 양방향 관계를 편리하게 관리하기 위해 사용됨.

 

사용하는 이유:

양방향 관계를 설정하고 싶으면, 한 쪽에서 관계를 설정하고 반대쪽에서도 이를 동기화해야 함.
이걸 수동으로 처리하면 실수하기 쉬움.
연관관계 메서드는 이를 한 번에 설정하도록 함.


 

 

 public void addChildCategory(Category child) {
 this.child.add(child);
        child.setParent(this);
    }


위 코드는 Category 엔티티의 부모-자식 관계를 설정하는 것임.
1. 현재 Category 엔티티(=this)의 자식 리스트에 child를 추가.
2. 추가된 child 엔티티의 부모를 현재 Categrooy(=this)로 설정.

 

 

왜 사용하는가??? (예시)

수동으로 설정하는 코드는 다음과 같음.

Category parent = new Category();
Category child = new Category();

parent.getChild().add(child);
child.setParent(parent);

 


위와 같이 Category parent, child를 두 번 호출해줘야 하므로 비효율적이게 됨.

연관관계 메서드를 만들어서 사용하면, 한 번의 호출로 양쪽 관계 모두 설정할 수 있음.

 

가령 Category 데이터로 전자제품, 스마트폰, 노트북, TV가 존재한다고 가정할 때,

'전자제품'만 부모로 만들고 나머지는 자식으로 설정하여 위계 관계를 만들고 싶을 때가 있음.

이러한 경우에는 다음과 같은 코드를 작성할 수 있음.

// 부모 카테고리 생성
Category parent = new Category();
parent.setName("전자제품");

// 자식 카테고리 생성
Category child1 = new Category();
child1.setName("스마트폰");

Category child2 = new Category();
child2.setName("노트북");

// 연관관계 설정
parent.addChildCategory(child1); // "스마트폰"을 "전자제품"의 자식으로 추가
parent.addChildCategory(child2); // "노트북"을 "전자제품"의 자식으로 추가

 

 


 

다른 예제

    public void setMember(Member member) {
        this.member = member;
        member.getOrders().add(this);
    }

 

위 코드는 Order 엔티티와 Member 엔티티간의 양방향 연관관계를 설정함.

하나의 Order가 하나의 Member에 속하고,

한 Member는 여러 Order를 가질 수 있는 구조를 설정함.

 

1. this.member = member;의 의미 

- 현재 Order 엔티티(=this)의 member 필드를 인자로 전달받은 member로 설정함.

- 즉, 주문(Order)에 회원(Member) 정보를 연결함.

Order order = new Order();
Member member = new Member();

order.setMember(member);

위 코드를 실행하면, 해당 주문(order)가 특정 회원(member)에게 연결됨.

 

2. member.getOrders().add(this);

- member.getOrders()는 회원의 모든 주문 목록을 반환함. 

- 이 리스트에 현재 Order 객체(=this)를 추가해 준다.

-> 즉, 회원이 소유한 주문 목록에 새로운 주문을 추가함.

 

전체 동작

- Order 객체가 특정 Member에 연결되고,

- 동시에 Member 객체의 주문 리스트에 새로운 Order 객체가 추가됨.

 

 


 

 

 

예제 시나리오

 

엔티티 설계 

@Entity
public class Member {
    @Id @GeneratedValue
    private Long id;

    @OneToMany(mappedBy = "member") // 연관 관계의 주인은 Order.member
    private List<Order> orders = new ArrayList<>(); // 회원의 주문 리스트
}
@Entity
public class Order {
    @Id @GeneratedValue
    private Long id;

    @ManyToOne
    @JoinColumn(name = "member_id") // 외래 키
    private Member member; // 주문의 회원
}

 

 

연관관계 설정 코드

Member member = new Member();
Order order = new Order();

// 연관관계 설정
order.setMember(member);

 

결과

order.member는 member를 참조함.

member.orders 리스트에 order가 추가됨.

 

 


 

 

 

연관관계 메서드 작성 TIP

 

1. 항상 "주인-비주인" 관계를 이해하기 

JPA에서는 연관관계의 주인만이 DB 외래 키를 관리한다.

연관관계 메서드는 주인과 비주인 모두를 동기화해야 한다.

 

예컨대, Order와 Member가 양방향 관계일 때: 

  • Order: @ManyToOne 주인 (외래 키를 관리)
  • Member: @OneToMany 비주인

 

이를 기반으로 연관관계 메서드를 작성한다.

public void setMember(Member member) {
    this.member = member;                // 주인 설정
    member.getOrders().add(this);        // 비주인 리스트 동기화
}

 

 

2. 메서드 작성 순서 기억하기

(1) 현재 객체의 필드 설정 (this.member = member)

(2) 상대방 객체의 필드도 동기화 (member.getOrders().add(this))

 

 

3. 단방향 연관관계는 간단히!

단방향 관계라면 메서드는 더욱 간단해진다. Order->Member일 경우에는...

public void setMember(Member member) {
    this.member = member; // 단순히 현재 객체의 필드만 설정
}

 

 

 

Copyright 2024. GRAVITY all rights reserved