연관관계 메서드란?
객체간 연관관계 설정시 사용하는 메서드.
주로 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; // 단순히 현재 객체의 필드만 설정
}