@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 |