티스토리 뷰

오늘 프로젝트에서 주요 도메인 모델들의 구조를 잡고 연관관계를 매핑하는 과정에서 삽질로 많은 시간을 소모해,
"당연하지만" 다시한번 깨달은 사실을 정리하고 기록해보기로 했다.

 

배경

상황은 비슷한 예시로 들어보면, 가장 이해하기 쉬운 게시글(Article) - 댓글(Comment)의 관계를 설정해보자.
Article(일) - Comment(다)의 일대다/다대일 양방향 연관관계 상태이다.
(물론 일대다는 가급적 자제하고 다대일만 매핑하는게 best practice이지만, 양방향이 꼭 필요한 상황이라고 가정해보자)

 

상황에 따른, 양방향 연관관계 Entity 값 저장 방식

양방향 연관관계 Entity를 save하면서, 당연한건데 큰 그림와 방향을 놓치고 있었다.
정리해보면 다음과 같다.
Article은 둘째치고, Comment의 저장에 초점을 맞춰보자.
이때, 물론 구현방법은 다양하지만, 가장 기본적이고 심플해보이는 방법으로 작성해봤다.

 

1. Article과 Comment를 한번에(동시에) 생성하고 저장하는 경우

  • (CommentService가 아닌) ArticleService를 통해 Comment를 저장한다.

  • 주의사항

    • (당연한것들인데, JPA가 처음이라면 삽질을 유발할 수 있다)

    • Article 생성자에 List 필드에 대한건 제외해야한다.

      • 평소처럼 인텔리제이 단축키를 이용해 constructor를 생성하면 모든 필드에 대해 생성되니 주의.
      • 따라서 필드에선 바로 List comments = new ArrayList<>(); 처럼 초기화해줘 버리자.
    • @OneToMany List에 CascadeType.ALL이 필요하다.

      • cascade 타입을 지정하지않으면 Article만 저장되고 Comment는 저장되지 않는것을 확인할 수 있을 것이다.
    • 당연히 Article.addComment(#) 메소드가 필요하다.

      • 우리의 목적은 Comment를 저장하는거였는데, 이런 add 메서드를 이용해 Article을 통해서 Comment를 저장한다.
      • 이때 추가할 comment의 Article필드가 채워져있어야한다.
      • 좀 못생겨도 article.addComment(new Comment(arg1, article)); 처럼 채우거나, add 메서드엔 인자만 넘기고 안에서 this.comment = new Comment(arg1, this); 처럼 정리할 수 도 있다.

// github 첫번째 커밋 참고

 

2. (Article은 이미 만들어져있고) Comment만 따로 저장하는 경우

  • CommentService를 통해 바로 저장한다.

  • (예전 jwp-blog 미션에서 우리가 Comment 저장하던 일반적인 방식. 보통 @OneToMany를 통한 리스트를 들고있는건 자제하므로 보통 이렇게 많이 저장. RESTful하기도하고)

  • 주의사항

    • new Comment()로 새로 만들어 save할건데, 이때 생성자 인자로 Article을 채워야한다. Article은 이미 만들어진 상황이므로 보통 articleId로 DB에서 Article을 꺼내 넣어준다.
    • 즉 CommentService에는 ArticleService가 필요해짐. 동시에 순환참조를 막기위해 ArticleService는 CommentService를 몰라야한다.

// github 두번째 커밋 참고

 

결론

결론은 Comment의 Article 필드가 반드시 채워져있어야한다.
그래야 안빠지고 제대로 들어간다. 왜냐면 Article(일) - Comment(다)의 관계에서 보통 키는 다쪽인 Comment가 가질테고, 당연히 Comment의 Article 필드가 채워져야한다. 그렇지않고 비운채로 Comment를 save하는 경우, article_id 필드가 비어있는것을 확인할 수 있었다.

첨언) 어쩌면 진짜 결론은, 결국 양방향을 쓰지 않는 것이다. 당시엔 프로젝트에서 위의 방식들로 값이 저장되도록 구현했지만, 나중에 결국 악의 근원인 OneToMany를 없애고 양방향을 풀어버렸더니 훨씬 코드로 깔끔해지고 머리도 안아파지더라.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함