자바 ORM 표준 JPA 프로그래밍 섹션6. 다양한 연관관계 매핑
연관관계 매핑 시 고려사항
- 다중성
- 다대일 @ManyToOne
- 일대다 @OneToMany
- 일대일 @OneToOne
- 다대다 @ManyToMany
- DB 관점에서 다중성을 고려하여 어노테이션을 붙이면 된다.
- 다대다는 실무에서 사용하지 않는다.
2. 단방향 vs 양방향
- 테이블은 외래키 하나로 양쪽 조인이 가능하며 사실 방향이라는 개념이 없다.
- 객체는 참조용 필드가 있는 쪽으로만 참조가 가능하며 한쪽만 참조하면 단방향, 양쪽이 서로 참조하면 양방향이다.
3. 연관관계의 주인
- 테이블은 외래키 하나로 두 테이블이 연관관계를 맺는다.
- 객체의 양방향 관계는 A→B, B→A 처럼 참조가 2군데이다. 따라서 둘 중 테이블의 외래키를 관리할 곳을 지정해야 한다. 이 외래키를 관리하는 참조가 연관관계의 주인이다. 그럼 주인의 반대편은 외래키에 영향을 주지 않고 단순 조회만 가능하게 된다.
모든 연관관계에 있어 앞에 오는 것이 연관관계의 주인이 된다. (Ex. "다대일" 일 경우 "다"에 해당하는 것이 연관관계의 주인이다.)
다대일 [N:1]
다대일 단방향
다대일 단방향의 객체와 테이블 연관관계는 아래와 같다. 외래키가 있는 곳에 참조를 걸어 연관관계 매핑을 하면 된다.
코드는 Member 쪽에서만 참조하도록 작성하면 된다.
@Entity
public class Team {
@Id @GeneratedValue
@Column(name="TEAM_ID")
private Long id;
private String name;
...
}
@Entity
public class Member {
@Id @GeneratedValue
@Column(name="MEMBER_ID")
private Long id;
@Column(name = "USERNAME")
private String name;
@ManyToOne
@JoinColumn(name="TEAM_ID")
private Team team;
...
}
다대일 양방향
다대일 양방향의 객체와 테이블 연관관계는 아래와 같다. 객체의 Team에 members가 추가되어도 테이블에는 영향을 주지 않는다. Team이 연관관계 주인이기 때문에 TEAM_ID로 연관관계를 관리하고 있기 때문이다.
코드는 양쪽을 서로 참조하도록 작성하면 된다.
@Entity
public class Team {
@Id @GeneratedValue
@Column(name="TEAM_ID")
private Long id;
private String name;
@OneToMany(mappedBy="team")
private List<Member> members = new ArrayList<>();
...
}
@Entity
public class Member {
@Id @GeneratedValue
@Column(name="MEMBER_ID")
private Long id;
@Column(name = "USERNAME")
private String name;
@ManyToOne
@JoinColumn(name="TEAM_ID")
private Team team;
...
}
일대다 [1:N]
일대다 단방향
일대다 단방향의 객체와 테이블 연관관계는 아래와 같다.
Team은 Member 리스트를 알고 싶지만 Member은 Team 정보가 필요없는 상황이다. 테이블 연관관계에서는 "다" 쪽에 외래키가 들어가야 하기 때문에 아래와 같이 MEMBER에 TEAM_ID라는 외래키가 생긴다. 이렇게 되면 Team의 members 값을 변경하게 되면 다른 테이블의 TEAM_ID를 업데이트 해야 한다.
즉 일대다 단방향은 "일"이 연관관계의 주인이나 테이블에서는 "다" 쪽에 외래키가 있다. 객체와 테이블의 차이 때문에 반대편 테이블의 외래키를 관리해야 하는 특이한 구조가 되는 것이다. 따라서 @JoinColumn을 꼭 사용해야 한다. 사용하지 않는다면 조인 테이블 방식을 사용하여 중간에 테이블을 하나 더 추가해야 한다.
이렇게 되어 아래 모델은 실무에서 권장되지는 않는다.
'Spring > SpringBoot&JPA' 카테고리의 다른 글
[JPA] 프록시, 즉시/지연 로딩, 영속성 전이(CASCADE), 고아 객체 (0) | 2024.04.01 |
---|---|
[JPA] 상속관계 매핑 (0) | 2024.03.29 |
[JPA] 연관관계 매핑 (단방향, 양방향, 연관관계의 주인) (0) | 2024.03.26 |
[JPA] 엔티티 매핑 (매핑 어노테이션, DDL, 기본키 전략) (0) | 2024.03.22 |
[자바 ORM 표준 JPA 프로그래밍] 섹션3. 영속성 관리 - 내부 동작 방식 (0) | 2024.03.18 |