<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 양방향을 쓰는게 좀 더 실무에 적합하지 않을까 생각이든다.
'공부 > JPA' 카테고리의 다른 글
<JPA> 낙관적락(Optimistic Lock), 비관적락(Pessimistic Lock) (0) | 2022.03.05 |
---|---|
<JPA> 영속성 컨텍스트 (0) | 2021.03.05 |
<Spring & JPA 웹서비스 만들기 > 구현 (5) - 달력 만들기 (0) | 2021.02.12 |
<Spring & JPA 웹서비스 만들기 > 구현 (4) - 화면 구성 (0) | 2021.02.06 |
<Spring & JPA 웹서비스 만들기 > 구현 (3) - Redis 자동완성 (0) | 2021.01.31 |
블로그의 정보
57개월 BackEnd
BFine