이 글은 이전글인
JPA - 연관관계 매핑(조인 방법), 단방향 연관 관계 및 매핑
과 이어집니다.
양방향 매핑 방법
- Member와 Team 테이블의 연관 관계로 설명
Member.java
@Entity
public class Member {
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
@Column(name = "USERNAME")
private String username;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
...
}
Team.java
@Entity
public class Team {
@Id
@GeneratedValue
@Column(name = "TEAM_ID")
private long id;
private String name;
@OneToMany(mappedBy = "team") // Member객체의 team과 연관관계 매핑
private List<Member> members = new ArrayList<>();
public List<Member> getMembers() {
return members;
}
- 양방향 매핑시 다대일(N:1)인 객체(Member)는
@ManyToOne
과@JoinColumn
을 이용해서 매핑했다. - 나머지 일대다(1:N)인 객체(Team)는
@OneToMany(mappedBy = "team")
을 이용해서 매핑했다. - 연관되는 서로의 객체를 멤버변수(매핑 컬럼 설정)로 등록 시켜서 매핑을 해야한다.
객체 탐색
Member findmember = em.find(Member.class, member.getId());
List<Member> members = findmember.getTeam().getMembers();
for(Member m : members) {
System.out.println("m.getUsername() = " + m.getUsername());
}
양방향 연관관계에서 테이블과 객체의 차이
테이블 연관관계 = 1개
- 회원 ↔팀의 연관관계 1개(양방향)
- 테이블은 외래 키(MEMEBER.TEAM_ID) 하나로 두 테이블의 연관관계를 관리
객체 연관관계 = 2개
- 회원 → 팀 연관관계 1개(단방향)
- 팀 → 회원 연관관계 1개(단방향)
- 객체의 양방향 관계는 서로 다른 단방향 관계 2개로 이루어져 있다.
객체 매핑에서 오는 딜레마
그렇다면, Member객체의 Team값을 바꿧을때, MEMBER.TEAM_ID값이 바뀌어야 하는지, Team객체의 List members 값을 바꿧을때 MEMBER.TEAM_ID값이 바뀌어야 하는지 어떻게 결정하는가?
→ 연관관계의 주인(Owner)으로 지정해서 관리
양방향 매핑 규칙
- 객체의 두 관계중 하나를 연관관계의 주인으로 지정
- 연관관계의 주인만이 외래 키를 관리(등록, 수정)
- 주인이 아닌쪽은 읽기만 가능
- 주인은 mappedBy 속성 사용X
- 주인이 아니면 mappedBy 속서으로 주인 지정
연관 관계의 주인(Owner) 지정 방법
- 외래키가 있는 곳을 주인으로 지정할것!
→ Team의 객체에서 값을 바꿧는데, MEMBER테이블에 쿼리문이 나가면 혼란스럽다. - 예시에서는 Member.team이 연관관계의 주인
양방향 매핑시 가장 많이 하는 실수
연관관계의 주인에 값을 입력하지 않는 경우 값이 들어가지 않음
연관관계의 주인에 값을 입력한 경우, 값이 잘 들어감
- 순수 객체 상태를 고려해서 항상 양쪽에 값을 설정할 것
→ 연관관계 편의 메소드를 생성하자
연관관계 편의 메소드
Member.java
public void setTeam(Team team) {
this.team = team; // 멤버에 팀을 세팅할 때
team.getMembers().add(this); // team의 Member값에 this값을 넣어서 Member값을 세팅해준다.
}
- 양방향 매핑시에 무한 루프를 조심할 것!
→ toString(), lombok , JSON 생성 라이브러리 사용시 양방향으로 매핑되면, 무한루프에 빠진다- toString 사용 x, lombok에서 toString 사용하는것 생성 x, JSON에서 엔티티 반환하는것 사용하지 말것 → dto로 변환해서 반환
양방향 매핑 정리
- 단방향 매핑으로도 이미 연관관계 매핑은 완료
- 양방향 매핑은 반대 방향으로 조회 기능이 추가된 것
- JPQL에서 역방향으로 탐색할 일이 많다.
- 단방향 매핑을 우선하고, 양방향이 필요할 때 추가 해도 된다. (양방향 추가시 테이블을 바꾸지 않기 때문에 코드 몇줄만 추가하면 되기 때문)
- 연관관계의 주인을 정하는 기준
→ 외래 키의 위치를 기준으로 정할 것!
참고
이글은 김영한 님의 JPA 프로그래밍 강의를 바탕으로 쓰여졌습니다
https://www.inflearn.com/course/ORM-JPA-Basic
반응형