🍃이 글은 inflearn에서 김영한의 스프링 부트와 JPA 실무 완전 정복 로드맵을 학습하고 작성한 것입니다.🍃
Member에서 Team으로 조회할 수가 없다.
객체를 테이블에 맞추어 연관관계가 없는 상태로 모델링 하면 객체 지향적인 설계가 아니다.
테이블은 외래키로 조인을 사용해서 연관된 테이블을 찾는다.
객체는 참조를 사용해서 연관된 객체를 찾아야 한다.
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
@Column(name = "USERNAME")
private String name;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
}
@ManyToOne: 연관관계 설정, 다 대 일
@JoinColumn: 외래키 매핑
Member에서 Team을 조회할 수 있다. (단방향 객체 그래프 탐색)
@Entity
public class Team {
@Id @GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "team")
List<Member> members = new ArrayList<Member>();
}
@OneToMany(mappedBy = "team")
Member에서 Team뿐만 아니라 Team에서 Member로도 조회할 수 있다. (양방향 객체 그래프 탐색)
객체 연관관계는 회원에서 팀, 팀에서 회원 이렇게 두 번의 참조로 양방향 관계를 맺는다.
테이블 연관관계는 외래키 하나로 양방향 관계를 맺는다.
위 예시처럼 객체가 양방향 연관관계로 했을 때 두 번의 참조 중에 어떤 참조로 외래키 매핑(연관관계 주인)을 해야 할까?
객체의 두 관계 중 하나를 연관관계 주인으로 지정한다.
연관관계 주인만 외래 키를 관리한다. (등록, 수정)
주인이 아닌 쪽은 조회만 가능하다.
주인이 아닌 쪽은 mappedBy 속성으로 주인을 지정해준다.
외래 키가 있는 곳(Many, '다' 쪽)을 주인으로 정한다.
연관관계 주인에 외래키 값을 입력해야 등록된다.
순수 객체 상태를 고려해서 양방향 매핑시 항상 양방향 모두에 외래키 값을 설정한다.
주인 쪽만 외래키 값을 넣었을 경우
DB에 외래키 값이 반영되기 전(INSERT SQL) 즉, 1차 캐시 상태에선 빈 컬렉션(members)을 조회하는 오류가 발생한다.
JPA를 사용하지 않는 순수 테스트 케이스 작성 시 빈 컬렉션(members)을 조회하는 오류가 발생할 수 있다.
연관관계 편의 메소드를 생성해서 외래키 값을 한쪽만 설정하는 실수를 줄이자.
public void addMember(Member member) {
memberList.add(member);
member.setTeam(this);
}
양방향 매핑시에 무한 루프를 주의하자.
toString()
lombok
엔티티를 직접 JSON으로 응답
toString()과 마찬가지로 엔티티가 JSON으로 변환하는 과정에서 양방향 연관관계로 인해 서로 호출되면서 무한루프가 발생한다.
엔티티 변경 시 API 스펙이 변경된다.
요청과 응답 시, 엔티티를 DTO로 변환해서 사용하자.
단방향 매핑만으로도 이미 연관관계 매핑은 완료된다.
양방향 매핑은 단지 반대 방향으로의 조회 기능만 추가된것이다.
설계할 때 우선 단방향 매핑만 하고, 양방향 매핑은 필요할 때 추가한다.