엔티티의 관계가 n:m 일 경우, 보통은 중간에 테이블을 더 두어 1:N, N:1 관계로 풀어 쓰는것이 좋다고 알고 있다.
그러나, n:m 관계를 유지한채 엔티티를 구성 하고 싶을경우, 일반적으로 사용하는 @JoinColumn 이 아닌 @JoinTable 을 통해
구성 할 수도 있고, 1:N 관계 이더라도 경우에 따라서는 JoinTable을 이용할 수 있다.
스프린트 미션을 진행하면서, 다음의 테이블 관계가 미리 정의된 채로 코드를 작성해야 하는 때가 있었다.
- A , B, C 테이블이 있다. A 테이블과 B 테이블은 1:1 관계, B 테이블과 C 테이블은 1:N 관계이다.
- A 테이블에는 B 테이블의 id를 FK로 참조한다.
- 원래대로 라면 B 테이블은 C 테이블의 id를 FK로 참조해야 한다. 그러나 이 경우, A <-> B 테이블의 관계에선 null 값이 되어 문제가 된다.
- 원래대로 라면 A 테이블과 C 테이블은 관계가 없으므로, B 테이블을 2개로 쪼개어 B-1, B-2 로 만들고, 각각 A, C 테이블과 연결하는게 좋다.
- 이를 해결하기 위해 중간에 연관 테이블인 D가 정의되어 있다.
- D 테이블은 B 테이블의 id 와 C 테이블의 id를 FK로 가지고 있다.
정리하자면, 다음과 같다.
- A - B 테이블(1:1)
- B - D 테이블(1:1)
- D - C 테이블 (N : 1)
여기서, C 테이블을 엔티티로 구현하여 코딩작업을 할 때, 통상적으론 D 테이블에 해당되는 엔티티를 만들어 구현하면 된다.
그러나 D 테이블은 단순히 연관 테이블이라 부가 정보가 없어 엔티티를 만들고 싶지 않을때 에도 @JoinTable 을 사용할 수 있다.
@BatchSize(size = 100)
@OneToMany(fetch = FetchType.LAZY, orphanRemoval = true, cascade = CascadeType.ALL)
@JoinTable(
name = "D테이블 이름",
joinColumns = @JoinColumn(name = "C_테이블_id"),
inverseJoinColumns = @JoinColumn(name = "B_테이블_id")
)
private List<B테이블 엔티티클래스> attachments = new ArrayList<>();
- joinColumns
- D 테이블에 명시된 C 테이블의 fk 값을 연결 시켜 준다.
- inverseJoinColumns
- 반대로, C 테이블 입장에서 B 테이블의 관계를 맺어야 하므로, D 테이블의 B테이블 fk를 연결하여 List 에 값을 받아올 수 있도록 한다.
이렇게 JoinTable 을 이용할 수도 있지만, D 테이블의 엔티티를 추가하여 JoinColumn을 이용하는 방법, 혹은 B 테이블을 쪼개는 방법이 더 낫다고 한다.
'Backend > SpringBoot' 카테고리의 다른 글
| Admin 페이지 설정하기 (0) | 2025.11.05 |
|---|---|
| @Valid, @Validated (0) | 2025.11.03 |
| BaseEntity 사용 및 time 정보 자동 생성 (0) | 2025.10.31 |
| Custom Annotation (Custom validation) (0) | 2025.10.29 |
| Json 형식으로 로깅 하기 + MDC (0) | 2025.10.29 |