intro : jpa의 연관관계 매핑에 대해 알아보자.
연관관계가 필요한 이유
다음과 같은 상황에 대해서 생각해보자. 회원과 팀이 있고 회원은 하나의 팀에만 소속될 수 있다. 회원과 팀은 다대일 관계이다. 이 내용을 토대로 객체를 테이블에 맞추어 모델링한 결과는 다음과 같다.
참조 대신에 외래키를 그대로 사용하여 Entity를 구성
외래키 식별자를 직접 다룸
식별자로 다시 조회, 객체 지향적인 방법은 아님
위 방법이 왜 객체지향적인 방법이 아니라고 말하는걸까 ?
객체는 참조를 사용해서 연관된 객체를 찾는다.
구성된 클래스에서 teamId를 통해 Member 클래스와 Team 클래스의 연관관계를 지정하고 있다. 이는 사실상 데이터베이스의 연관관계 방식을 객체에 그대로 적용한 것으로, 객체지향적 관계와는 거리가 멀다고 할 수 있다. 데이터베이스 중심의 매핑은 객체의 본질적인 특징인 캡슐화와 추상화를 무시하고, 단순히 데이터 저장소의 구조를 따라가는 방식이다. JPA를 활용할 때는 객체지향적 연관관계 매핑을 통해 객체의 본질을 유지하고 데이터 처리의 복잡성을 줄이는 것이 중요하다. 객체의 연관성을 직접 매핑하고, 이를 통해 자연스러운 탐색과 유지보수 가능한 설계를 구현해야 한다. 이는 객체지향적인 코드와 데이터베이스 간의 간극을 효과적으로 줄여주며, 장기적으로 더 나은 성능과 가독성을 제공한다.
단방향 연관관계
위 상황과 다르게 이번엔 객체 중심으로 모델링한 결과는 다음과 같다.
객체의 참조와 테이블의 외래 키를 매핑 (위 상황과 다르게 객체 자체로 키 매핑)
연관관계 저장
참조로 연관관계 조회 - 객체 그래프 탐색
연관관계 수정
양방향 연관관계와 연관관계 주인
이번에는 객체가 단방향 연관관계가 아니라, 양방향 연관관계인 경우이다. 테이블은 외래키 하나로 양쪽 테이블의 데이터를 조회할 수 있지만, 단방향으로 설정된 객체에서는 Member는 Team을 알 수 있어도 Team에서는 Member를 알 수 없다.
Member 엔티티는 단방향 동일
Team 엔티티는 컬렉션 추가 (members), mappedBy
사용
반대 방향으로 객체 그래프 탐색
연관관계 주인과 mappedBy
객체와 테이블간에 연관관계를 맺는 차이를 이해해야 한다.
객체의 연관관계는 2개이다, 회원에서 팀으로의 연관관계 + 팀에서 회원으로의 연관관계 2개. 테이블 관점에서는 회원에서 팀의 pk값을 가지고 있기에 연관관계는 하나지만 양방향으로 조회할 수 있다. 정리하자면 테이블은 외래 키 하나로 두 테이블의 연관관계를 관리한다 그렇다면 객체에서 또한 어느 곳에서 하나로 외래키를 관리해야 한다. 이때 사용하는것이 mappedBy인데, 주인이 아닌곳에 속성을 사용하게 된다. 보통 주인을 결정할 때는 외래키가 있는 곳을 주인으로 정한다. 위 상황 에서는 Member.team이 연관관계의 주인이 된다.
양방향 매핑시 가장 많이 하는 실수
양방향 매핑시 연관관계의 주인에 값을 입력해야 한다.
순수한 객체 관계를 고려한다면 항상 양쪽 다 값을 입력해야 한다. (Member에 Team을 설정해 줘야 한다.)
양방향 연관관계 주의!
순수 객체 상태를 고려해서 항상 양쪽에 값을 설정하고, 실수할 수도 있으니 연관관계 편의 메소드를 생성해서 사용하자 (권장) set
보다 change
라는 단어가 포함된 이름의 메소드를 구성하는게 관례이며 보통 연관관계 메소드는 한쪽에만 작성한다. 추가적으로 양방향 매핑시에는 무한루프를 조심해야 하는데 toString()
, lombok
, JSON 생성 라이브러리
등 무한 루프에 빠질 수 있다.
양방향 매핑 정리
단방향 매핑 만으로도 이미 연관관계 매핑은 가능하다. 양방향 매핑은 반대 방향으로 조회(객체 그래프 탐색) 기능이 추가된 것 뿐이다. JPQL 에서 역방향으로 탐색할 일이 많다. 단방향 매핑을 잘 하고 양방향은 필요할때 추가하는게 더 좋다. (어차피 테이블 구성에 영향을 주지 않는다.)
연관관계의 주인을 정하는 기준
비즈니스 로직을 기준으로 연관관계의 주인을 선택하면 안되고, 외래키의 위치를 기준으로 정해야한다. 보통 외래키가 있는곳이 연관관계의 주인이다. 객체와 테이블의 모델링을 그림으로 한번 그려보면 외래키가 어디에 있어야 하는지 눈에 쉽게 들어오니 그려보고 판단하는게 좋아 보인다.