[Spring] 엔티티 간의 연관 관계 매핑

zini9188·2023년 2월 25일
0

Spring

목록 보기
25/33

엔티티의 연관 관계

연관관계 매핑에서 고려할 점

  • 다중성 (일대다, 다대일, 일대일, 다대다)

  • 방향 (양방향, 단방향)

  • 연관관계의 주인

단방향 연관 관계

한쪽 클래스만 다른 쪽 클래스의 참조 정보를 가지고 있는 관계

Member에서만 Order를 참조하여 값을 가져올 수 있음

양방향 연관 관계

양쪽 클래스가 서로의 참조 정보를 가지는 관계

Member와 Order 둘 다 서로를 참조하여, 값을 가져올 수 있음

일대다(1 : N) 연관 관계

  • 외래키는 다(N)에서 관리하여 일(1)이 연관관계의 주인이 된다.

  • JPA에서 지원하지만, 실무에서는 권장하지 않음

  • 일대다 단방향 연관관계에서는 반드시 @JoinColumn을 사용

    • 사용하지 않는 경우 JoinTable 방식을 사용
@Entity
public class Post {
    @Id @GeneratedValue
    private Long postId;
    
    private String title;
}

@Entity
public class Board {
    @Id @GeneratedValue
    private Long boardId;
    
    private String title;

    @OneToMany
    @JoinColumn(name = "POST_ID") 
    List<Post> posts = new ArrayList<>();
}

권장하지 않는 이유

  • 실사용을 할 때 (1)을 수정하였지만 다른 수정이 생겨 쿼리가 발생 (업데이트 쿼리로 인한 성능상 이슈는 크지 않음)

  • 다대일 양방향 연관 관계를 매핑하는 것이 추후 유지보수에 수월

결론

일대다 연관관계는 다대일 단방향 매핑을 한 후, 필요한 경우 일대다 단방향 매핑을 추가하여 양방향 연관 관계를 만드는 것이 일반적

다대일 (N : 1) 연관 관계

  • 외래키를 다(N)에서 관리하는 연관 관계이고 N이 주인이 된다.

  • 단방향의 경우 다(N) 쪽에 @ManyToOne만 추가

  • 양방향을 만들기 위해서는 일(1)에 @OneToMany를 추가하고 연관 관계의 주인을 mappedBy로 지정

  • 양방향에서는 외래 키가 있는 곳이 연관관계의 주인이 된다.

@Entity
public class Post {
    @Id @GeneratedValue
    private Long postId;

    private String title;

	// 다(N)에서 필수
    @ManyToOne
    @JoinColumn(name = "BOARD_ID")
    private Board board;
}

@Entity
public class Board {
    @Id @GeneratedValue
    private Long boardId;
    
    private String title;
    
    // 양방향인 경우 추가
    @OneToMany(mappedBy = "board")
    List<Post> posts = new ArrayList<>();
}

일대일 (1 : 1) 연관 관계

주 테이블에 외래키를 넣을 수도 있고, 대상 테이블에 외래키를 넣을 수도 있음

다대일 연관 관계 매핑과 동일하지만 @ManyToOne 어노테이션이 아닌 @OneToOne 어노테이션을 사용

엔티티 간의 연관 관계 매핑 권장 방법

  • 일대다 매핑을 사용하지 않는다.

  • 가장 먼저 다대일 단방향 매핑을 적용한다.

  • 다대일 단방향 매핑을 통해 객체 그래프 탐색으로 조회할 수 없는 정보가 있으면, 양방향 매핑을 적용한다.

Cascade 영속성 전이

어떠한 엔티티를 영속화할 때, 해당 엔티티와 연관된 엔티티도 함께 영속화하고 싶을 때 사용하는 기능이다.

public enum CascadeType {
    ALL,      // 아래 모든 경우, 전이
    PERSIST,  // 영속화 할 때, 전이
    MERGE,    // 병합 할 때, 전이
    REMOVE,   // 삭제 할 때, 전이
    REFRESH,  // 새로고침할 때, 전이
    DETACH;   // 부모 엔티티가 detach 호출 시, 자식도 detach 전이
}
profile
백엔드를 지망하는 개발자

0개의 댓글