Jemrello 프로젝트에서 card 기능 구현 중, catalog와의 연관관계 매핑에서 변경 전이가 상황에 따라 다르게 발생할 수 있음을 알게 되었다.
card와 catalog는 1:n 관계로 @OneToMany
매핑되어 있었는데 card를 save할 때, catalog의 cardList에 자동으로 card가 저장되지 않아 리스트가 empty 상태인 것을 발견하게 되었다.
// catalog entity
@OneToMany(mappedBy = "catalog", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Card> cardList = new ArrayList<>();
// card entity
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "catalog_id")
private Catalog catalog;
일반적인 @OneToMany
관계에서는 자식 엔티티를 저장하면 부모 엔티티에 대한 변경이 발생할 때 자동으로 업데이트 된다. 특히 cascadeType.all을 사용하면 연관된 엔티티에 대한 모든 변경이 전파되는 것을 명시적으로 설정할 수 있다.
그러나 fetchType이 Lazy로 설정되면 로딩이 지연되어 연관 엔티티들이 즉시 로드되지 않고 실제로 사용될 때 로드된다. 즉, cardList가 즉시 업데이트 되지 않을 수 있는 것이다. 이외에도 JPA 구현 방식에 따라 자동 업데이트가 실행되지 않는 경우가 발생할 수 있음을 알게되었다.
이를 해결하기 위한 방법으로 부모 엔티티에 대한 변경이 발생한 후 연관된 엔티티를 명시적으로 업데이트하도록 하였다. 즉, card가 save된 후, catalog의 cardList를 불러와 직접 card를 add 하도록 구현하였다.
//card service
cardRepository.save(card);
catalog.getCardList().add(card);
수동으로 추가하니 잘 작동하는 것을 확인할 수 있었다.