ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • JPA에서 양방향 매핑은 언제 쓰일까? ( feat . JPQL )
    Spring & JPA 2023. 11. 18. 20:37

     

    데이터베이스에서 테이블끼리 관계는 FK(외래키)를 참조하는 방식으로 이뤄져있다.

     

    외래키로 관계가 맺어져있다면,  아무곳에서 join을 걸어서 원하는 데이터를 얻을 수 있다. 

     

    즉 DB에선 JPA의 OneToMany처럼 두 클래스 중 한쪽에서만 참조하고있는 단방향이라는 개념이 존재하지 않는다. 

     

     

    select m.member_id
    from member m
    join team t on t.TEAM_ID = m.TEAM_ID

     

    다음 Member와 Team 테이블이 있을 때 두 테이블을 잇는 데 방향이랄게 없다.


     

    그런데 이게 JPA로 넘어가면 방향이란게 생긴다. 

    방향이 왜 생길까? 

     

    Jpa를 이용한다는 결국 자바를 쓰는건데,  객체들끼리 참조값을 이용하기 때문이다.

     

    똑같이 Member와 Team이 있다.

     

    만약 Team 객체가 주어진 상황일때,  member 참조 변수가 없다면 접근할 수 없어진다. 

    결국엔 값을 얻기 위해 Team에 members도 참조해서 양방향으로 참조하게 된다.

     

    나같은 JPA을 아직 공부하고있거나 처음 접하는 사람들한텐 어찌보면 양방향 참조를 하는게 당연하게 생각이 들 수 있다.

     

    '음 ~ 특정 Team 정보 조회시 member 리스트를 참조할 수 있으면  해당 팀의 모든 회원 리스트 뽑아 올수 있으면 좋지 않을까?' 라는 생각으로 말이다.

     

     

     

    나 또한 토이프로젝트 할때 예매-티켓이 1:N 관계였는데

    하나의 예매단위가 당연히 티켓리스트를 갖고있어야 한다고 생각해서 양방향 매핑을 했었다. 


     

    JPA에서 양방향 매핑을 쓴다는 것은

     

    대게 @OneToMany 와 @ManyToOne을 양쪽 테이블에 걸어주는 상황일 것이다.

     

    하지만 특정 객체가 @OneToMany를  들고있는것이 수도 없이 많다면..? 그 객체가 갖는 책임이 너무 많아지는 것 아닐까?

     

    ex)

     

    한 주문 시스템에서 회원(Member)은  주문, 장바구니, 리뷰 대게 모든 객체와 상호작용 할 때,

    특정 회원의 주문 리스트, 장바구니 리스트 ,리뷰 리스트를 

    과연 아래처럼 회원에 모두 @OneToMany로 양방향 매핑을 해줘야할까?

     

    class Member{
    
    	@OneToMany(mappedBy = "member")
    	private List<Order> orders;
    
    	@OneToMany(mappedBy = "member")
    	private List<Review> reviews;
    
    	@OneToMany(mappedBy = "member")
    	private List<Basket> basket;
    }

     

     

    이렇게 되면 회원이 갖는 책임이 너무 많아지는 것이 아닐까? 

     

    회원이 주문내역, 리뷰내역, 장바구니 내역 모두 들고있는게 맞나? 라는 생각이 들 수 있다.


     

    특정 회원(로그인한 사용자)이 쓴 리뷰 목록을 불러온다 할 때

     

    시스템이 돌아가는 원리를 생각해보면, 전체 리뷰 리스트에서 사용자 필터링을 통해 리뷰를 찾아올 것이다.

    (회원마다 리뷰를 저장하진 않을거라고 생각한다. 물론 할 순 있지만...  그렇게되면 다른 곳에서 리뷰 정보를 가져다 못쓰니까)

     

    여기서 JPQL 개념이 필요한데, JPQL은 (jpa 환경) 엔티티 중심으로 쿼리를 짤 수 있도록 도와준다.

     

    즉 객체간 참조값이 없더라도 db처럼 fk만 있다면 조인을 통해 원하는 데이터를 찾아낼 수 있다.

     

    SELECT m.id, m.name
    FROM Members m
    JOIN m.reviews r

     

    JPQL 조인 작업을 통해  원하는 값을 가져올 수 있어서

     

    @OneToMany를 통한 참조값으로 리스트를 부를 필요가 없다.

     

    (그리고 양방향 매핑시 무한루프 가능성도 존재한다.)

     


     

    결론 

     

    JPA 대부 김영한님이 말씀하시기론, 실무에서도 단방향 매핑으로 모든 설계가 끝나야한다고 말씀하신다.

     

    필요한 부분은 쿼리를 직접 짜서 실행시키고, 모든 설계를 단방향 매핑으로 끝낸 다음에 !!!

     

    꽤나 복잡한 역방향 쿼리를 양방향 매핑으로 바꿈으로써 쉽게 풀어낼 수 있는 경우가 있다면,

     

    단방향 매핑을 양방향 매핑으로 바꾸는 작업을 시도하라고 하셨다.

     

     

     

     

     

     

     


    Reference

     

    https://www.inflearn.com/course/ORM-JPA-Basic/dashboard

Designed by Tistory.