Backend/SpringBoot

@JoinTable

Dean83 2025. 10. 31. 14:35

엔티티의 관계가 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