[JPA] 연관관계 매핑
객체가 지향하는 패러다임과 관계형 데이터베이스가 지향하는 패러다임이 달라 객체 설계 시 테이블 설계에 맞춰서 설계하면 객체 그래프를 탐색할 때 문제가 생긴다.
테이블은 외래 키를 사용해 연관된 테이블을 찾고, 객체는 참조를 사용해 연관된 객체를 찾는다.
두 패러다임의 불일치 때문에 객체지향적으로 코드를 작성할 수 없다.
객체의 참조와 데이터베이스 테이블의 FK를 매핑해 패러다임의 불일치를 해결하자.
단방향 연관관계
Member와 Team을 묶는다고 생각해보자.
Team에는 여러 Member가 속할 수 있다. (Member가 N, Team이 1인 상황이다)
Member에 Team의 외래 키를 필드로 가지는 방식으로 설계하면 위에서 언급한 문제가 발생한다.
위와 같은 방식으로 설계하고 싶다.
이 때 @ManyToOne 애너테이션과 @JoinColumn 애너테이션을 사용한다.
Member 입장에서는 Many, Team입장에서 One인 상황이다.
(하나의 Team에 여러 Member가 포함된다)
객체에서의 Team 레퍼런스와 데이터베이스에서의 TEAM_ID와 매핑되니 @JoinColumn 애너테이션을 설정한다. (생략가능)
왼쪽과 같이 작성 시 객체의 Team과 데이터베이스의 TEAM_ID가 연관관계로 매핑된다.
객체에서는 이렇듯 연관관계가 단방향으로 설정되지만, 데이터베이스 테이블에서는 FK 하나로 두 군데 모두에서 JOIN을 수행할 수 있어 양방향 연관관계로 설정된다.
양방향 연관관계
단방향 연관관계에서 한 단계 더 나아가보자.
Team 에서 Team에 소속된 Member를 바로 찾을 수 있도록 설계하자.
테이블의 연관관계는 외래 키 하나로 끝나니 테이블은 수정할 필요가 없지만, 객체는 다르다.
Team 객체에서 Member List를 넣어 줘야 Team에서 Member를 찾을 수 있게 된다.
Team 객체에 List를 추가하자.
이 때 @OneToMany 애너테이션을 사용하고,
mappedBy 속성을 통해 어떤 멤버 필드와 연관되는지 명시해 준다.
양방향 연관관계 정의 시 @JoinColumn는 하나의 엔티티에만 정의하고 나머지 엔티티에는 mappedBy 속성을 사용한다.
객체에는 연관관계가 두 가지가 있다.
1. Member -> Team
2. Team -> Member
즉, 단방향 연결관계가 두 개가 있어 양방향 연결관계인 것 처럼 보인다.
객체와 데이터베이스 테이블이 서로 매핑돼야 하는데..
객체에는 두 가지 연관관계가 있고 테이블에는 연관관계가 하나 뿐이다. 그럼 두 개 중 어떤걸 기준으로 매핑해야 할까?
Member의 Team으로 매핑해야하나? 아니면 Team의 List<Member>로 매핑해야되나?
여기서 연관관계의 주인이라는 개념이 등장한다.
양방향 매핑에서는 객체의 두 관계 중 하나를 연관관계의 주인으로 지정해야 한다.
연관관계의 주인만 외래 키를 관리할 수 있고, 주인이 아닌 쪽은 읽기만 가능하다.
주인은 mappedBy 속성을 사용하지 않는다.
그리고, 외래 키가 있는 객체가 연관관계의 주인이 된다.
데이터베이스 입장에서는 외래 키가 있는 부분이 N(多) 이고, 외래키가 없는 부분이 1이다.
데이터베이스와 객체를 어떻게 매핑할까? -> 연관관계의 주인은 어떻게 설정할까?
이 흐름을 기억하자.
외래 키가 있는 객체를 연관관계의 주인으로 설정해야 직관적으로 이해하기 쉽고, 깔끔하게 설계된다.
먼저 데이터베이스를 설계한 후 엔티티를 설계하는 편이 합리적이다.
데이터베이스 테이블을 설계할 때 FK를 가진 테이블을 엔티티로 옮길 때, 그 엔티티를 연관관계의 주인으로 설정하자.
연관관계의 주인만 데이터베이스의 연관관계와 매핑되고 FK를 관리할 수 있고, 주인이 아닌 쪽은 읽기만 할 수 있다.
그렇다고 항상 연관관계의 주인에만 값을 넣어주기보다는, 객체와 데이터베이스 상태를 일관성 있게 유지하기 위해 양방향 매핑을 사용할 때는 연관관계의 주인 엔티티와 주인이 아닌 엔티티 두 군데에 값을 넣어주자. (편의 메서드를 사용하자)
양방향 연관관계를 설정해서 얻을 수 있는 이점은 객체 그래프 탐색 기능 뿐이다.
단방향 매핑만으로 객체와 테이블 간의 매핑은 완료되니 객체 그래프 탐색 기능이 필요한 경우 양방향 연관관계를 지정하고 사용하자.
'Spring > JPA' 카테고리의 다른 글
[JPA] 상속관계 매핑 (0) | 2022.12.23 |
---|---|
[JPA] 다양한 연관관계 매핑 (0) | 2022.12.22 |
[JPA] 객체와 테이블 매핑 (0) | 2022.12.22 |
[JPA] 영속성 컨텍스트 (0) | 2022.12.21 |
[JPA] 도입 (0) | 2022.12.21 |
댓글
이 글 공유하기
다른 글
-
[JPA] 상속관계 매핑
[JPA] 상속관계 매핑
2022.12.23 -
[JPA] 다양한 연관관계 매핑
[JPA] 다양한 연관관계 매핑
2022.12.22 -
[JPA] 객체와 테이블 매핑
[JPA] 객체와 테이블 매핑
2022.12.22 -
[JPA] 영속성 컨텍스트
[JPA] 영속성 컨텍스트
2022.12.21