일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- Seek_Keyset
- wappalyzer
- DB생성
- MySQL
- appleM1
- 이클립스
- VUE
- Postman
- SQL
- K8S
- Java
- minikube
- 우분투에war배포
- restful api
- windows10
- intellij
- offset
- gradle
- spring
- CloutNative
- MYSQL에러
- String
- frontend
- SpringBoot
- 스프링에러
- pagination
- springMVC
- MySQL시작하기
- NullPointerException
- Lombok
- Today
- Total
미운 오리 새끼의 우아한 개발자되기
[JPA] 연관관계 매핑 기초 (2) 양방향 연관관계 본문
1. 양방향 연관관계
양방향 연관관계란 다음과 같다
- 회원 -> 팀
- 팀 -> 회원
2. 양방향 연관관계의 매핑
@Entity
public class Member {
@Id
@Column(name = "MEMBER_ID")
private Long id;
private String username;
// 연관관계 매핑
@ManyToOne // 다(Member)대일(Team)
@JoinColumn(name = "TEAM_ID") // 외래키를 매핑할 때 쓰는 annotation. 매핑할 외래키 이름을 씀
private Team team;
// 연관관계 설정
public void setTeam(Team team) {
this.team = team;
}
// Getter, Setter...
}
@Entity
public class Team {
@Id
@Column(name = "TEAM_ID")
private Long id;
private String name;
// 연관관계 매핑
@OneToMany(mappedBy = "team") // 일(Team)대다(Member)
private List<Member> members = new ArrayList<>();
// Getter, Setter...
}
mappedBy 속성은 양방향 매핑을 때 사용하는데 반대쪽 매핑의 필드명을 값으로 주면 된다.
사실 객체에는 양방향이라는 것이 없음. 테이블의 경우에는 FK 하나로 두 테이블이 서로 조인해서 사용 가능하니 양방향이지만, 객체의 경우에는 단방향 2개로 양방향인것 처럼 구현하는 것임.
근데 이렇게 단방향 2개를 사용(즉 양방향)하면, 회원 -> 팀, 팀-> 회원으로 두 곳에서 서로를 참조하므로 관리 포인트가 2개로 늘어나버림.
테이블의 경우에는 FK 하나만 관리하면 되는데..
이런 차이로 인해 JPA 에서는 두 객체 연관관계 중 하나를 정해 테이블의 FK 를 관리하게 하는데 이것을 연관관계의 주인(Owner)라고 함.
3. 양방향 매핑의 규칙: 연관관계의 주인
양방향 연관관계 매핑 시 두 연관관계 중 하나를 주인으로 정해야만 함.
이 주인만이 외래키를 관리(등록, 수정, 삭제)할 수 있고 주인이 아닌 쪽은 읽기만 가능.
누가 주인인지 아닌지를 mappedBy 속성으로 나타내는 것.
- 주인은 mappedBy 속성을 사용하지 않는다.
- 주인이 아니면 mappedBy 속성을 사용해서 속성의 값으로 연관관계의 주인을 지정해야한다.
주인을 정한다는 것은 사실 FK 관리자를 선택하는 것이다.
4. 양방향 연관관계의 주의점
연관관계의 주인만이 외래키의 값을 변경할 수 있다.
즉, Member 객체를 통해서만 필드의 값을 변경할 수 있고, Team 객체를 통해 member 의 값을 변경할 수는 없다.
-> 양방향이라면서..?
-> 고로, 양방향 연관관계는 양쪽 다 신경 써야한다. 양방향이 깨지지 않도록!
아래와 같이 양방향이 깨지지 않도록 구현을 해줘야함.
관계형 DB 에서는 FK 하나로 해결하지만, 객체에서 양방향 연관관계를 사용하려면 로직을 견고히 작성해야함.
public void setTeam(Team team) {
// 기존 팀과의 관계 제거
if (this.team != null) {
this.team.getmembers().remove(this);
}
this.team = team;
team.getMembers().add(this();
}
5. 정리
- 단방향 매핑 만으로 테이블과 객체의 연관관계 매핑을 이미 완료됨.
- 단방향을 양방향으로 만들면 반대방향으로 객체 그래프 탐색 기능이 추가됨.
- 양방향 연관관계를 매핑하려면 객체에서 양쪽 방향을 모두 관리해야함.
연관관계 주인을 정하는 기준은 비즈니스 중요도를 배제하고 단순히 FK 관리자 정도의 의미만 부여해야함.
Reference : 자바 ORM 표준 JPA 프로그래밍 (김영한 저)
'Spring & Spring Boot > Spring' 카테고리의 다른 글
[JPA] 다양한 연관관계 매핑 (3) 일대일 (0) | 2023.04.11 |
---|---|
[JPA] 다양한 연관관계 매핑 (2) 일대다 (0) | 2023.04.11 |
[JPA] 다양한 연관관계 매핑 (1) 다대일 (0) | 2023.04.11 |
[JPA] 연관관계 매핑 기초 (1) 단방향 연관관계 (0) | 2023.04.09 |
[Spring MVC] Spring MVC 작동 원리 (0) | 2020.09.07 |