티스토리 뷰
[JPA] 양방향 연관관계 주인 @ManyToOne / @OneToMany / MappedBy 선언위치
foodev 2022. 7. 11. 19:43[요약]
1대多
多에 1을 조회할 수 있는 fk가 존재
多는 연관관계의 주인
多에서 @Joincolum선언은 1을 조회할 수 있는 fk를 나타냄
1에서는 mappedBy를 통해 단순조회
1대1
연관관계 주인으로 선언한 곳에
@JoinColumn(name = "종속관계_id")
연관관계의 종속에
@MappedBy("주인 객체")
1. 객체와 테이블 서로 다른 연관관계
[Member와 Team의 연관관계]
객체와 테이블을 표현한 그림이다.
객체, PK, FK에 주의하여 살펴보자
- 객체 연관관계 포인트 2가지
- 회원-> 팀 1개
- 팀 -> 회원 연관관계 1개
- 테이블 연관관계 1가지
- 회원 <-> 팀의 관계
- FK와 PK로 양쪽의 연관관계를 알 수 있다.
[객체의 양방향 관계]
- 객체의 양방향 관계는 사실 양방향 관계가 아니라 서로 다른 단 반향 관계 2개다.
- 객체를 양방향으로 참조하려면 단방향 연관관계를 2개 만들어야 한다.
예시
A -> B (ex: a.getB())
B -> A (ex: b.getA())
2. @ManyToOne과 @OneToMany
@Entity
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "member_id")
private Long id;
@Column(name = "user_name")
private String name;
@ManyToOne
private Team team;
}
@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<>();
}
[Member입장에서]
1. 다수
2 Member에 ManyToOne 선언
[Team입장에서]
1. 소수
2. Team에 OneToMany선언
3. MappedBy선언
3. MappedBy는 Member와 Team 중 어디에 선언할까?
[테이블의 양방향 관계]
외래키 하나로 두 테이블의 연관관계를 정의한다.
Member의 TEAM_ID(FK)를 통해 TEAM을 알 수 있고, TEAM의 TEAM_ID(PK)를 통해 MEMBER를 알 수 있다.
4. 결론 : Member와 Team 중 어디에서 키를 관리할까?
~~에 의해 MappedBy 됐어 즉, 종에게 MappedBy를 선언한다.
[양방향 매핑 규칙]
1. 객체의 두 관계중 하나를 연관관계의 주인으로 지정
2. 연관관계의 주인만이 외래 키를 관리(등록, 수정)
3. 주인이 아닌쪽은 읽기만 가능
4. 주인은 mappedBy 속성 사용하지 않음
5. 주인이 아니면 mappedBy 속성으로 지정
[누구를 주인으로 할까?]
⭐️⭐️⭐️⭐️외래키가 있는 곳을 주인으로 정한다. (외래키는 보통 多쪽)
외래키 = 多 = 주인
@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(strategy = GenerationType.AUTO)
@Column(name = "member_id")
private Long id;
@Column(name = "user_name")
private String name;
@ManyToOne
private Team team;
}
여기에서는 Member.team이 연관관계 주인
추가) @JoinColumn
[Member입장에서]
Member가 Join하는 컬럼을 선언
@JoinColumn(name = "team_id")
private Team team;
해석하자면 Team 객체에서 가지고 있는 team_id를 통해 Join하겠다는 어노테이션
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "member_id")
private Long id;
@Column(name = "user_name")
private String name;
@ManyToOne
@JoinColumn(name = "team_id")
private Team team;
}
혹시 더 좋은 방법이 있다면 댓글로 피드백 부탁드리겠습니다! 감사합니다.
'💻 개발 > JPA, Querydsl' 카테고리의 다른 글
[Querydsl] 연관관계가 없는 테이블 연결 하기 / 연관관계 없는 엔티티 외부조인 (0) | 2022.08.16 |
---|---|
[JPA] @Inhertance 조인 전략 / 상속관계 매핑 (0) | 2022.07.30 |
[JPA] @Entity란? / @Entity주의사항 / 리플랙션 (0) | 2022.07.10 |
[JPA] 영속성 컨텍스트 | JPA 내부에서 어떻게 동작하는가? (0) | 2022.07.09 |
[Querydsl][오류] Cannot delete or update a parent row: a foreign key constraint fails (0) | 2022.07.08 |
- Total
- Today
- Yesterday