<JPA> 연관관계 타당성 분석하기
왜 JPA를 사용할 경우 객체간 연관관계의 타당성을 따져야 할까요?
이는 테이블이 다른 테이블에 접근하는 방식과 객체가 다른 객체에 접근하는 방식의 차이 때문에 발생합니다.
테이블의 경우 우리는 잘 알고있는 FK 값을 활용해서 Join 연산을 통해 다른 테이블로 접근해 데이터를 뽑아옵니다.즉,FK를 가지고 있는 모든 테이블은 해당 FK가 PK로 설정된 테이블에 Join으로 접근가능하며 그 반대로 PK를 가진 테이블도 FK를 가진 테이블로의 Join연산이 가능합니다.
결론적으로 테이블간의 접근은 무방향성을 가진다고 볼 수 있습니다.
하지만 객체의 경우 얘기가 달라집니다.
ORM이라는 것 자체가 최대한 RDB스럽게 객체를 활용하자라는 패러다임을 가지는데 이러다 보니 간극이 생긴 부분이 존재합니다.객체의 경우 하나의 클래스 내에 필드값으로 또 다른 객체가 선언되어 있으면 참조를 통해 자신이 아니 다른 객체에 접근 할 수 있습니다.
그래서 테이블의 관계를 객체로 옮겨오다보니 자연스레 양방향 연관관계라는 개념이 생겨났습니다.예를 들어 자유롭게 무역을 하던 두 국가간에 새로운 규약이 생겨 제약 조건이 생긴것으로 이해하셔도 좋습니다.
RDB에서의 테이블의 관계 일대일,다대일,일대다,다대다를 참고하여 이러한 관계를 그대로 양 쪽 엔티티에 적용해야 객체지향스럽게 RDB에 접근이 가능해진것입니다.그리고 가장 많이 사용되는 일대다,다대일의 경우 테이블의 세계에서는 무방향성을 띄었지만 객체세계로 옮겨 올때는 일대다는 필수적으로 맺어야 하는 연관관계가 되고 다대일은 제품의 요구사항에 맞춰 설계하는 선택사항이 되었습니다.(일대다 관계만 맺을 경우를 단방향 연관관계라고 합니다)
즉, 개발자가 프로덕트의 쓰임새에 알맞게 접근 할 수 있는 객체들을 정의할 수 있게 된 것입니다.
사실 필자도 JPA를 처음 접하고 마냥 디비에 쿼리가 날라가는것이 신기하고 귀찮은 SQL을 쓰지 않는게 그저 좋아 JPA가 만능 무기인것처럼 느낀적이 있었습니다.하지만 프로젝트를 진행할수록 제대로 기반을 다지지 않으면 나중에 큰 장애를 만날것 같은 느낌이 들어 아래와 같이 진행중인 프로젝트에 대한 연관관계 정리를 진행해봅니다.사실 먼저 아래와 같은 설계를 진행하고 개발에 착수하는것이 순리인데 어쩌다보니 순서가 뒤바뀐것도 사실입니다.하지만 정리해보니 확실히 하길 잘했다라는 생각이 듭니다.
아래는 제가 진행하는 프로젝트의 연관관계입니다.빨간선은 상속을 나타내고 주황색 선이 연관관계를 나타냅니다. 본격적으로 분석을 해보겠습니다.
User and Post(일대다)
- user : post ⇒ 일대다(사용자가 쓸 수 있는 게시글은 여러개)
– Post가 연관관계의 주인,즉 Post 엔티티가 user 인스턴스를 @ManyToOne으로 가져야함 - post : users ⇒ 다대일 필요한가?
– User 엔티티가 Post 엔티티를 List로 가져야할 명분이 있을까?– User 객체를 디비에서 뽑아올때 본인이 작성한 Post 데이터를 끌어와야 할까?
– 필요하다 → 양방향 매핑
User and Comment(일대다)
- user : comment ⇒ 일대다
– Comment가 연관관계의 주인,즉 Comment 엔티티가 user 인스턴스를 @ManyToOne으로 가져야함 - comment : user ⇒ 다대일 필요한가?
– User 엔티티가 Comment 엔티티를 List를 가져야할 명분이 있을까?– User가 자신이 작성한 댓글을 전부 끌어올 필요가 있을까?
– 추후 결정 필요
User and Like(일대다)
- user : like ⇒ 일대다(사용자는 여러개의 게시글에 좋아요를 누를수 있다)
– Like가 연관관계의 주인,즉 Like 엔티티가 user 인스턴스를 @ManyToOne으로 가져야함 - like : user ⇒ 다대일 필요한가?
– User 엔티티가 Like 엔티티를 List로 가져야할 명분이 있을까?– User가 본인이 누를 좋아요 누른 게시글을 알아야할 필요가 있을까?
– 추후 결정 필요
---
Post and Like(일대다)
- post : like ⇒ 일대다
– Like가 연관관계의 주인,즉 Like 엔티티가 post 인스턴스를 @ManyToOne으로 가져야함 - like : post ⇒ 다대일 필요한가?
– Post엔티티가 Like 엔티티를 List로 가져야할 명분이 있는가?– 게시글이 자신이 받을 좋아요의 갯수를 알아야 할 필요가 있을까?
– 필요하다 → 양방향 매핑
Post and Comment(일대다)
- post : comment ⇒ 일대다
– Comment가 연관관계의 주인,즉 Comment 엔티티가 post 인스턴스를 @ManyToOne으로 가져야함 - comment : post ⇒ 다대일 필요한가?
– Post 엔티티가 Comment 엔티티를 List로 가져야할 명분이 있는가?– 게시글이 자신에게 달린 댓글 데이터를 가져와야할 필요가 있을까?
– 필요하다 → 양방향 매핑
Post and Image(일대다)
- post : image ⇒ 일대다
– Image가 연관관계의 주인,즉 Image 엔티티가 post 인스턴스를 @ManyToOne으로 가져야함 - image : post ⇒ 다대일 필요한가?
– Post 엔티티가 Image 엔티티를 List로 가져야할 명분이 있는가?– 게시글이 자신에게 등록된 사진들에 대한 데이터를 받아올 필요가 있을까?
– 필요하다 → 양방향 매핑
Post and Tag(일대다)
- post : tag ⇒ 일대다
– Tag가 연관관계의 주인,즉 Tag 엔티티가 post 인스턴스를 @ManyToOne으로 가져야함 - tag : post ⇒ 다대일
– Post 엔티티가 Tag 엔티티를 List로 가져야할 명분이 있는가?– 게시글이 본인에게 설정된 태그값 데이터를 가져야할 필요가 있을까?
– 필요하다 → 양방향 매핑
---
해놓고 보니 복잡한것 처럼 보였던 테이블들의 관계가 생각보다 별거 없어보입니다.실제로 테이블 수도 그렇게 많지도 않구요.물론 프로토타입인지라 추후에 추가가 될 수도 있지만 기능 추가가 될 경우에도 꾸준히 업데이트를 해가며 설계를 먼저하고 개발에 들어가는 습관을 들여야겠습니다.