본문 바로가기

JPA

JPA - 단방향 @OnetoMany 연관관계 설정 시 단점

@CollectionElement, 단방향 @ManyToOne 혹은 양방향 셋 중 하나를 선택하는 경우가 잦았다. JPA를 처음 공부한 이후로 남은 기억은 @OneToMany를 지양하라는 것 뿐이었다. 지양하는 이유는 희미해져갔는데 이번 기회에 다시 정리하려고 합니다.

 

목차

1. 단방향 OneToMany 단점


단방향 OneToMany 단점

단방향 OneToMany은 성능과 유지보수 두 측면에서 문제를 발생시킨다.

 

첫 째는 외래키의 관리이다.

@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Group {

    @Id @GeneratedValue(strategy = IDENTITY)
    @Column(name = "group_id")
    private Long id;

    @JoinColumn(name = "group_id")
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Task> tasks = new ArrayList<>();

 

테이블 측면에서 외래키는 Group이 아닌 Task에서 가져가게 된다. 하지만 JoinColumn이 외래키 반대쪽에 설정되면서 관리측면에서 혼동을 줄 수 있다.

 

둘 째는 성능적인 부분이다.

본인 테이블에 외래 키가 있으면 엔티티의 저장과 연관관계 처리를 INSERT 한 번으로 끝낼 수 있다. 하지만 다른 테이블에 외래 키가 있으면 연관관계 처리를 위한 UPDATE 쿼리를 한 번 더 날려야 한다.

 

실제로 한 번 확인해보도록 하자.

 

[
            {
                "chapterId"1,
                "title""01장: 협력하는 객체들의 공동체"
            },
            {
                "chapterId"2,
                "title""02장: 이상한 나라의 객체"
            },
            {
                "chapterId"3,
                "title""03장: 타입과 추상화"
            },
            {
                "chapterId"4,
                "title""04장: 역할, 책임, 협력"
            },
            {
                "chapterId"5,
                "title""05장: 책임과 메시지"
            },
            {
                "chapterId"6,
                "title""06장: 객체 지도"
            },
            {
                "chapterId"7,
                "title""07장: 함께 모으기"
            }
        ]

 

이런 식으로 7개의 Task 엔티티 데이터를 넣어야 하고 각각마다 Group 엔티티와의 연관관계를 설정해야 한다. 이를 위해 INSERT 쿼리를 날린 후 아래와 같이 UPDATE 쿼리도 INSERT 쿼리 만큼 날린다.

 

 

물론 batch_size가 설정되어 있어서 실제로 데이터베이스에서 날리는 쿼리는 아래처럼 한 번에 모와서 보낸다.

 

하지만 크게 좋아보이진 않는다. 단방향의 장점은 애플리케이션 레벨에서 신경써야할 부분이 적다는 것이라고 생각하는데 단방향 OneToMany는 잃는 것이 많다. 앙뱡향을 설정하자.

 

 

'JPA' 카테고리의 다른 글

JPA - 기본 키 매핑 IDENETITY vs SEQUNECE  (0) 2023.05.22
JPA - 값 타입 컬렉션 주의 사항  (0) 2023.05.21
JPA - @JoinColumn, mappedBy  (0) 2023.05.12
JPA - 2차 캐시 알은 채 하기  (0) 2023.05.06
JPA - 값 타입  (0) 2023.04.07