Be ready to study forever - 개발자 꿈나무

[JPA] 다양한 연관관계 매핑-2 본문

Programming/JPA

[JPA] 다양한 연관관계 매핑-2

루눌룹 2021. 1. 23. 17:52

연관관계를 매핑할 때 고려해야할 것 3가지는:

-      다중성(1:N, N:1, 1:1, N:M)

-      단방향, 양방향

-      연관관계 주인

인데, 조합을 따져보면

N:1 단방향 (@ManyToOne)

N:1 양방향 (@ManyToOne<-> @OneToMany)

1:N 단방향 (@OneToMany)

1:N 양방향 (@OneToMany <-> @ManyToOne)

1:1 양방향 (@OneToOne <-> @OneToOne)

N:M 양방향 (@ManyToMany <-> @ManyToMany)

정도의 관계가 나올 수 있다. 관계가 나올 수 있는 조합이 많아서 특징별로 다 외워야 하나라고 생각 할 수도 있지만, 몇 가지 주의할 만한 관계를 제외하고는 원칙은 같다. 연관관계의 주인은 @ManyToOne쪽이 가져 가는게 맞다고. 그리고 설계시에 가능한한 단방향에서 끝낼 수 있으면 구지 양방향으로 연결 하지 않는 게 좋고, 나중에 양방향이 필요하다면 반대쪽에 어노테이션만 달아주면 된다. 이유는 양방향으로 가져가면 어쩔 수 없이 생기는 리스크(사람의 실수) 예를들면 mappedBy 필드에다 업데이트를 하는 경우(DB에 반영 안됨…) 가 생기기 때문에.

 

연관관계 주의점)

1:N 단방향 (@OneToMany)은 단방향이기 때문에 One쪽에서 외래키를 관리하게 된다.

그림과 같이 Team 객체에서 Member의 외래키를 관리하게 되면 직관적이지 않고 예상치 못한 쿼리가 나갈 수 있기 때문에 이러한 경우에는 1:N 단방향 (@OneToMany)보다 1:N 양방향 (@OneToMany <-> @ManyToOne)으로 설계 전략을 가져가는 좋다.

 

1:1 양방향 (@OneToOne <-> @OneToOne)

1:1 JPA에서는 단방향을 지원하지 않고 있다. 그리고 DB에서의 설계는 외래키에 unique constraint를 걸게 되면 1개의 엔티티에 1개의 유니크한 외래키 밖에 들어올 수 없으므로 1:1 관계가 된다. 그럼, 1:1 양방향 (@OneToOne <-> @OneToOne)@ManyToOne쪽은 없지만 외래키가 있는 쪽이 연관관계 주인이 되는 것이 바람직 하다. 그럼 어디에 외래키를 심는게 좋을까? 는 사실 생각이 좀 필요한 문제이다. 장단점을 비교해 보자면,

주 테이블에 외래 키

-      주 객체가 대상 객체의 참조를 가지는 것 처럼 주 테이블에 외래 키를 두고 대상 테이블을 찾음

-      객체지향 개발자 선호

-      JPA 매핑 편리

-      장점: 주 테이블만 조회해도 대상 테이블에 데이터가 있는지 확인 가능

-      단점: 값이 없으면 외래 키에 null 허용

 

대상 테이블에 외래 키

-      대상 테이블에 외래 키가 존재

-      전통적인 데이터베이스 개발자 선호

-      장점: 주 테이블과 대상 테이블을 일대일에서 일대다 관계로 변경할 때 테이블 구조 유지

-      단점: 프록시 기능의 한계로 지연 로딩으로 설정해도 항상 즉시 로딩됨(프록시는 뒤에서 설명)

 

N:M 양방향 (@ManyToMany <-> @ManyToMany)

다대다 양방향 매핑은 아주 편리해 보이지만 실무에서는 쓰이지 않는다.

@ManyToMany로 어노테이션을 걸게 되면 조인 테이블에 추가적으로 값을 넣을 수 없기 때문이다. 사실은 하다못해 createdAt, lastUpdatedAt 정도라도 들어가야 하는데 넣을 수가 없다 ㅠㅠ.

따라서 실무에서는 직접 조인트 테이블을 만들어서 사용한다.

관계 매핑 어노테이션의 속성)

@JoinColumn

 

@ManyToOne

 

@OneToMany

요약하자면

1. 단방향 매핑으로 끝낼 수 있으면 단방향 매핑으로 끝내는게 좋다,

2. 연관관계 주인은 @ManyToOne에서 가져 가는게 바람직하다.

3. 1:N (@OneToMany) 단반향 관계보다 양방향으로 설계 하는게 바람직하다.(@ManyToOne에 연관관계 주인을 설정하기 위해서)

4. 1:1(@OneToOne)관계는 단방향 X, 외래키가 있는 쪽이 연관관계 주인을 가져가고, 외래키는 전략에 따라 놓는다.

5. @ManyToMany 관계는 조인트 테이블에 추가적으로 관계를 심을 수 없기 때문에 사용하지 말고 @OneToMany -> @ManyToOne, @ManyToOne <- @OneToMany 직접 조인트 테이블을 만들어 사용해라.

'Programming > JPA' 카테고리의 다른 글

[JPA] 엔티티매핑  (0) 2021.01.24
[JPA] 고급 매핑 - 3  (0) 2021.01.23
[JPA] 연관관계 매핑 기초 - 1  (0) 2021.01.23
[JPA] 영속성 컨텍스트란?  (0) 2021.01.23
[JPA]실행하기  (0) 2021.01.22
Comments