단방향 매핑
예제 시나리오
• 회원과 팀이 있다.
• 회원은 하나의 팀에만 소속될 수 있다.
• 회원과 팀은 다대일 관계다.

@Entity
public class Member {
@Id @GeneratedValue
private Long id;
@Column(name = "USERNAME")
private String name;
private int age;
// @Column(name = "TEAM_ID")
// private Long teamId
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
//팀 저장
Team team = new Team();
team.setName("TeamA");
em.persist(team);
//회원 저장
Member member = new Member();
member.setName("member1"); //단방향 연관관계 설정, 참조 저장
member.setTeam(team);
em.persist(member);
//조회
Member findMember = em.find(Member.class, member.getId());
//참조를 사용해서 연관관계 조회
Team findTeam = findMember.getTeam();
// 새로운 팀B
Team teamB = new Team();
teamB.setName("TeamB");
em.persist(teamB);
// 회원1에 새로운 팀B 설정
member.setTeam(teamB);
양방향 매핑

Member 엔티티는 단방향과 동일함
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
@Column(name = "USERNAME")
private String name;
private int age;
// @Column(name = "TEAM_ID")
// private Long teamId
@ManyToOne
@JoinColumn(name = "TEAM_ID") //상대편 테이블의 "TEAM_ID"컬럼과 매핑한다.
private Team team;
Team 엔티티는 members 필드 추가
@Entity
public class Team {
@Id @GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "team") // 여기서 "team"은 주인쪽 Team 타입의 필드명이다.
List<Member> members = new ArrayList<Member>();
…
}
//조회
Team findTeam = em.find(Team.class, team.getId());
int memberSize = findTeam.getMembers().size(); //역방향 조회
연관관계의 주인과 mappedBy
객체와 테이블이 관계를 맺는 차이
객체 (연관관계 2개)
• 회원 -> 팀 연관관계 1개(단방향)
• 팀 -> 회원 연관관계 1개(단방향)
객체의 양방향 관계는 서로 다른 단방향 관계가 2개 있는것이다.
테이블 (연관관계 1개)
• 회원 <-> 팀의 연관관계 1개(양방향)
연관관계의 주인(Owner)
양방향 매핑 규칙
- 객체의 두 관계중 하나를 연관관계의 주인으로 지정
- 연관관계의 주인만이 외래 키를 관리(등록, 수정)
- 주인이 아닌쪽은 읽기만 가능
- 주인은 mappedBy 속성 사용X
- 주인이 아니면 mappedBy 속성으로 주인 지정
주인지정
- 외래키가 있는 곳을 주인으로 정해라
- 비즈니스 로직과는 관계 없음
양방향 매핑시 흔한 실수
Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setName("member1");
//역방향(주인이 아닌 방향)만 연관관계 설정
team.getMembers().add(member);
em.persist(member);

연관관계의 주인에 값을 설정해야 한다!
member.setTeam(team);
양방향 연관관계 주의
- 순수 객체 상태를 고려해서 항상 양쪽에 값을 설정하자
- 연관관계 편의 메소드를 생성하자(주인또는 반대편에 상황에 따라 적절하게 생성하자)
- 연관관계 편의 메소드 : 한쪽을 변경 할 때 그 상대편도 같이 변경이 되도록하는 (세터)메서드 작성
- 무한루프 조심 (예, toString(), lombok, JSON 생성 라이브러리(DTO로 리턴하도록 히자))
양방향 매핑 정리
- 단방향 매핑만으로도 이미 연관관게 매핑은 완료된다.
- 양방향 매핑 반대 방향으로 조회(객체 그래프 탐색) 기능이 추가된 것 뿐
- JPQL에서 역방향으로 탐색할 일이 많음
- 단방향 매핑을 잘 하고 양방향은 필요할 때 추가해도 됨 (테이블에 영향을 주지 않음)
'JPA' 카테고리의 다른 글
[JPA 프로그래밍] - 07. 고급 매핑 (0) | 2024.05.08 |
---|---|
[JPA 프로그래밍] - 06. 다양한 연관관계 매핑 (0) | 2024.05.06 |
[JPA 프로그래밍] - 04. 엔티티 매핑 (0) | 2024.04.06 |
[JPA 프로그래밍] - 03. 영속성 관리 (0) | 2024.03.02 |