Blog

[TIL] 편의메소드를 통한 연관관계 일관성 유지

작성날짜
2023/09/19
작성자
최종 편집 일시
2023/11/15 00:53
Review 엔티티와 Store 엔티티는 1:N 연관관계며 양방향 관계이기도 합니다.
Review.java 엔티티클래스에서 setStore() 메소드를 통해 아래와 같이 양방향 연관관계를 맺고 있습니다.
@Table(name = "reviews") public class Review extends TimeStamped { ... @JsonIgnore @JoinColumn(name = "store_id") @ManyToOne(fetch = FetchType.LAZY) private Store store; ... public void setStore(Store store) { this.store = store; }
Plain Text
복사
Review 엔티티클래스는 Store 엔티티클래스와 양방향 관계에 있습니다. (리뷰:가게 <=> N:1 양방향)
서로의 필드를 조회 할 수 있는 상태라는 말과 같습니다.
@OneToMany(mappedBy = "store", orphanRemoval = true) private List<Review> reviewList = new ArrayList<>();
Plain Text
복사
하지만 문제가 있습니다.
일관성을 유지하지 못할 가능성이 있습니다.
따라서 아래와 같은 세터 메소드를 작성해서 일관성을 보완해야 합니다.
public void setStore(Store store) { this.store = store; if (!store.getReviewList().contains(this)) { store.getReviewList().add(this); } }
Plain Text
복사
위 메소드를 설명하면
리뷰:가게 = N:1이면서 양방향인 경우에
리뷰(N)는 키주인인 가게(1)에서 리뷰 목록으로 담기게 되는데
실제로 List에 존재하는지 여부를 체크하고
없는 경우 리뷰객체본인 자체를 리뷰리스트에 추가시키면서 양쪽을 항상 동일하게 유지하게 됩니다.
따라서 리뷰(N)에서는 위 setter 메소드를 통해
리뷰 객체 본인이 들어 갈 가게의 리뷰목록에서 자기자신을 체크하고 없으면 넣는 로직 작성해야 일관성이 유지되고
DB뿐만 아니라 Java의 시점에서도 리뷰객체와 리뷰리스트객체간의 일관성이 유지됩니다.
그런데 여기서 추가적으로 살펴볼 문제가 있습니다.
객체를 JSON으로 변환하는과정 직렬화 중 무한루프에 빠지지않도록 작성한 @JsonIgnore는 필드를 무시하면서 양방향관계가 끊어지게 됩니다.
그럼 @JsonIgnore를 사용하지 않고도 순환 참조 문제를 해결해야 하고 동시에 양방향 참조를 이어가야 합니다.
위 기본 setStore 메서드를 아래와 같이 보완해야 합니다.
public void setStore(Store store) { this.store = store; if (store != null && !store.getReviewList().contains(this)) { store.getReviewList().add(this); } }
Plain Text
복사
이렇게 하면 @JsonIgnore를 사용하지 않고도 양방향 연관관계를 유지하면서 순환 참조 문제를 해결할 수 있습니다.