Ep4. 연관관계 매핑

yumyeonghan·2023년 2월 4일
0

JPA

목록 보기
4/10

🍃이 글은 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 엔티티와 반대 연관관계 설정, 일 대 다
    • 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()

      • toString()호출시, 즉 객체를 호출할 때 양방향 연관관계로 인해 서로 호출되면서 무한루프가 발생한다.
    • lombok

      • @ToString 어노테이션 사용 주의하자.
    • 엔티티를 직접 JSON으로 응답

      • toString()과 마찬가지로 엔티티가 JSON으로 변환하는 과정에서 양방향 연관관계로 인해 서로 호출되면서 무한루프가 발생한다.

      • 엔티티 변경 시 API 스펙이 변경된다.

      • 요청과 응답 시, 엔티티를 DTO로 변환해서 사용하자.

양방향 매핑 정리

  • 단방향 매핑만으로도 이미 연관관계 매핑은 완료된다.

  • 양방향 매핑은 단지 반대 방향으로의 조회 기능만 추가된것이다.

  • 설계할 때 우선 단방향 매핑만 하고, 양방향 매핑은 필요할 때 추가한다.

    • JPQL 사용할 때 양방향으로 탐색할 일이 많다.
profile
웹 개발에 관심 있습니다.

0개의 댓글