You will be fine

<JPA> @OneToMany 단방향으로 쓰지 않는 이유

by BFine
반응형

가.  양방향

 a. 무엇인가

  -  JPA의 연관관계 뿐만 아니라 객체참조, 레이어, 패키지 등등 단방향으로 하는 것이 좋다. 

  -  그 이유는 양방향으로 연관관계나 참조가 걸리는 경우 예기치 못한 오류나 동작을 경험할 수 있기 때문이다. 

 

 b.  Spring Bean 순환참조

  -  AService <-> BService 에 각각 서로의 Bean에 대해 의존성 주입을 한다면 아래와 같은 오류를 볼 수 있다.

     =>  Spring 에서는 순환참조가 발생하면 아래와 같이 application이 실행되지 않고 종료된다.

 

 c.  @ToString 

  -  JPA에서 양방향 관계인 경우에 참조엔티티 포함해서 @ToString을 하게 되면 무한루프가 발생하게 된다.

 

나.  단방향이 하라면서.. @OneToMany는 왜..?

a.  @ManyToOne 단방향으로 하면 되지 않을까?

  -  OneToMany 양방향으로 쓰지말고 ManyToOne 단방향 하라는 이야기를 볼 수 있다. 그렇지만 전부 해당되는 이야기는 아니다.

  -  예를들어 게시판과 댓글 엔티티가 있다면 ManyToOne 이면 댓글 엔티티에만 게시판으로 가는 통로가 존재하게된다. 

  -  물론 게시판 id 를 가지고 댓글들을 조회해도 되겠지만 게시판 엔티티만 두고 봤을때 게시판과의 연관관계는 찾아볼수 없게 된다.

 

b.  @OneToMany 단방향으로 설정하는 방법

  -  @OneToMany에서 단방향으로 설정하려면 @JoinColum 을 이용하면 된다. 

  -  여기서 Lesson과 LessonDetail이 있고 Lesson에서 LessonDetail로 가는 통로(참조)만 있고 역은 존재하지 않는다.

      => 객체의 관점에서 봤을때 단방향이어서 적절해보인다.

 

 c.  @OneToMany 단방향에서 상위 Entity를 영속화 한다면..? 

  - Lesson에 LessonDetail을 저장하고 영속화 한 뒤 쿼리를 확인해보면 예상한 쿼리랑 다르고 특히 update 쿼리가 발생할것을 확인 할 수 있다.

  - LessonDetail 들을 먼저 insert 하고 Lesson 을 insert 하면 4번의 쿼리로 끝일텐데 왜 불필요하게 update 쿼리가 발생할까?

  - 그거는 LessonDetail Entity에 Lesson(lesson_id)가 없기 때문에 JPA 입장에서는 LessonDetail에서 lesson_id를 추가할 방법이 없다

   => 그렇기 때문에 먼저 insert를 한 뒤에 부모의 id를 가지고 다시 update 하고 있다.

 - 4번의 쿼리면 끝날 것을 자식 엔티티 만큼의 update 쿼리가 나가는 것은 비효율적으로 볼 수 있다. 또한 update 쿼리가 나갈것이라고 인식 못할수도 있다.

 

 d. 모르는 값(FK)을 관리하고 있는게 맞을까..? 

   - JPA가 객체와 테이블간에 패러다임 불일치를 해결해주는 목적으로 나온 ORM 이긴 하지만 이경우에는 올바른 것 인지가 고민되는 것 같다.

  - 엔티티 상에는 lesson_id를 lesson_detail이 관리 안하는것 처럼 보이지만 테이블상에서는 관리하고 있다.

  - 내 생각에는 update 쿼리가 나가는것도 문제지만 LessonDetail 만 보았을때 이부분을 전혀 확인 할 수 없고 Lesson 까지 봐야 알 수가 있다.

  - 그래서 @OneToMany 단방향 보다는 @OneToMany-@ManyToOne 양방향을 쓰는게 좀 더 실무에 적합하지 않을까 생각이든다. 

반응형

블로그의 정보

57개월 BackEnd

BFine

활동하기