JPA 스터디 (3) 다양한 연관관계 매핑, 고급매핑

Jihoon Oh·2022년 6월 23일
0

JPA 스터디

목록 보기
3/4
post-thumbnail

섹션 6. 다양한 연관관계 매핑

연관관계 매핑 시 고려할 것

다중성

  • 다대일(@ManyToOne)
  • 일대다(@OneToMany)
  • 일대일(@OneToMany)
  • 다대다(@ManyToMany)

단방향과 양방향

  • 테이블은 방향이라는 개념 x
  • 객체에서 한 쪽만 참조하면 단방향, 양쪽이 서로 참조하면 양방향

연관관계의 주인

  • 데이터베이스 외래 키를 관리하는 객체
    • 보통 외래 키를 가진 테이블과 매핑한 엔티티
    • mappedBy x

이후 설명하는 다대일, 일대다 연관관계에서 회원(Member)은 다(N), 팀(Team)은 일(1)로 서로 관계를 맺는다. 회원에서 팀 쪽으로 연관관계를 맺을 경우 Member.team으로 객체 참조를 하고, 팀에서 회원쪽으로 연관관계를 맺을 경우 Team.members로 컬렉션(List, Set 등)을 통한 참조를 한다.

다대일

다대일 단방향 [N:1]

  • 회원(N)은 Member.team으로 팀(1) 엔티티를 참조할 수 있음
  • 팀에는 회원을 참조하는 필드가 없는 연관관계
  • N쪽의 필드를 @JoinColumn 을 이용해 외래 키와 매핑
    • Member.team필드로 회원 테이블의 TEAM_ID 외래 키를 관리

다대일 양방향 [N:1, 1:N]

  • 회원(N)은 Member.team으로 팀(1) 엔티티를 참조할 수 있음
  • 팀(1)도 Team.members로 회원(N) 엔티티를 참조할 수 있음
  • 항상 다(N) 쪽에 외래 키가 있음
    • 다 쪽이 연관관계의 주인이 되어야 함
    • 주인이 아닌 연관관계는 조회를 위한 JPQL이나 객체 그래프 탐색에 사용
  • 연관관계의 주인 쪽에는 @JoinColumn, 반대쪽에는 mappedBy를 사용
  • 항상 서로를 참조해야 함
    • 한 쪽만 참조하면 양방향 연관관계 성립 x
    • 한 쪽 엔티티에 연관관계 편의 메서드를 작성해서 사용

일대다

일대다 단방향 [1:N]

  • 팀(1)이 Team.members로 회원(N)을 참조하고 회원은 팀 참조 불가
  • Team.members가 회원 테이블의 TEAM_ID 외래 키를 관리
  • 외래 키는 다(Member) 쪽에 있는데 관리는 일(Team) 쪽에서 함
  • @JoinColumn을 명시해야 함
    • 명시하지 않으면 Member의 외래 키를 사용하는게 아니라 조인 테이블 전략을 사용해서 매핑하게 됨
    • 현구막 기술 블로그에 나온 @JoinColumn 생략은 @ManyToOne의 상황임에 주의
  • 매핑한 객체가 관리하는 외래 키가 다른 테이블에 있는 점이 단점
    • INSERT문 한번으로 엔티티의 저장과 연관관계 처리를 끝내지 못하고 연관관계 처리를 위한 UPDATE문을 추가로 실행해야 함
    • why? Member 엔티티는 Team엔티티를 모르므로 MEMBER 테이블의 TEAM_ID를 저장할 수 없음
      • 이후에 Team.members 참조를 확인해서 TEAM_ID를 업데이트 해주어야 함
  • 따라서 일대다 단방향 매핑 대신 다대일 단방향 매핑 사용을 권장

일대다 양방향 [1:N, N:1]

  • 그런 거 없다.
  • 양방향 연관관계를 맺으려면 연관관계의 주인이 아닌 쪽에 mappedBy를 사용해야 함
    • @ManyToOne에는 mappedBy가 없음
    • 따라서 @OneToMany는 연관관계의 주인이 될 수 없음
    • 일대다 단방향 매핑 반대편에 같은 외래 키를 사용하는 다대일 단방향 매핑을 읽기 전용으로 하나 추가하는 방법으로 우회는 가능하나, 이는 꼼수에 불과하며 일대다 단방향 매핑의 단점을 그대로 가짐 → 쓰지 말자
  • 결론적으로 양방향 매핑을 하게 되면 거의 대부분 다대일 양방향 매핑을 사용하게 됨

일대일 [1:1]

일대일 관계의 특징

  • 일대일 관계는 그 반대도 일대일 관계
  • 주 테이블이나 대상 테이블 둘 중 어느 곳이나 외래 키를 가질 수 있음

주 테이블에 외래 키

  • 외래 키를 객체 참조와 비슷하게 사용 가능
    • 주 테이블만 확인해도 대상 테이블과 연관관계가 있는지 확인 가능
    • 객체지향 개발자들이 선호
  • MemberLocker가 일대일로 연관관계를 맺는다고 가정했을 때, Member 쪽이 외래 키와 객체 참조를 모두 가지는 경우
    • Member.locker@OneToOne으로 매핑
  • 단방향의 경우 다대일 단방향(@ManyToOne)과 거의 비슷
  • Locker.member필드를 추가하고 @OneToOne(mappedBy = "locker")를 추가해주면 양방향 연관관계가 맺어짐
    • mappedBy를 통해 Locker가 연관관계의 주인이 아님임을 명시

대상 테이블에 외래 키

  • JPA에서는 일대일 단방향 관계에서 대상 테이블에 외래 키가 있는 경우를 지원 x
  • 따라서 연관관계 방향을 수정하거나 양방향으로 만들고 대상 테이블 엔티티를 연관관계의 주인으로 설정해야 함
  • 주 테이블의 엔티티에 @OneToOne(mappedBy = ), 대상 테이블의 엔티티에 @OneToOne@JoinColumn을 사용하여 매핑
    • 사실상 주 테이블에 외래 키 방식과 객체 구현 방식은 같음

다대다 [N:N]

관계형 데이터베이스는 정규화된 테이블 2개로 다대다를 표현할 수 없음 → 연결 테이블 사용

  • 각각의 테이블에 FK를 넣을 수 있는 컬럼은 1개 뿐이므로
  • 회원(MEMBER)과 상품(PRODUCT) 모두 다(N)에 해당하는 관계
  • MEMBER_IDPRODUCT_ID를 컬럼으로 가지는 연결 테이블 MEMBER_PRODUCT를 만들어 다대다 관계를 일대다, 다대일 관계로 풀어내야 함
    • 외래 키는 MEMBER_PRODUCT에 있음
    • MEMBER_PRODUCTMEMBER_IDPRODUCT_ID를 외래 키로 가지며, 또한 이 두 개가 기본 키가 됨
  • 이는 데이터베이스의 이야기로, 객체는 서로 컬렉션으로 참조하는 방식으로 다대다 가능
  • 다대다 매핑에는 @ManyToMany 사용
    • 엔티티에서는 연결 테이블을 신경 쓰지 않아도 됨
  • 연관관계 매핑 시 연결 테이블에 INSERT 쿼리가 날아감
  • 연관관계 조회 시(엔티티의 컬렉션을 통한 조회) 연결 테이블과 조회 대상을 조인하는 쿼리가 날아감

다대다 단방향

회원(MEMBER)→상품(PRODUCT)으로만 연관관계가 있는 회원-상품 다대다 관계

  • 다대일, 일대다, 일대일에서는 @JoinColumn을 사용했다면 다대다에서는 @JoinTable 사용
    • why? 위에서도 언급했든 컬럼에 외래 키를 매핑할 수 없으니(어느 쪽에 연관관계를 주어도 FK가 여러 개가 됨) 연결 테이블을 사용해야 함
    • @JoinTable.name: 연결 테이블을 지정
    • @JoinTable.joinColumns: 매핑할 조인 컬럼 정보를 지정
      • 예를 들어 MEMBER@JoinTable을 사용했으면 joinColumns속성은 MEMBER_ID로 지정
    • @JoinTable.inverseJoinColumns: 반대 방향으로 매핑할 조인 컬럼 정보를 지정
      • MEMBER@JoinTable을 사용했으면 PRODUCT_ID로 지정

다대다 양방향

  • 역방향에도 @ManyToMany 사용
  • 연관관계의 주인이 아닌 쪽에 mappedBy 속성 사용
  • 연관관계의 주인 쪽은 단방향과 마찬가지로 @JoinTable 사용하면 됨
  • 다대일 양방향과 마찬가지로 연관관계 편의 메서드를 사용하는 것이 유리

다대다 매핑의 한계와 연결 엔티티

편해 보이지만 실무에서 사용하기에 한계가 있음

  • 연결 테이블이 숨겨져 있으므로 예상하지 못한 쿼리가 생길 수 있음
  • 연결 테이블에 추가 정보가 들어가면 @ManyToMany사용 불가능
    • 예를 들어 주문 수량, 날짜, 시간 등의 정보 추가
    • 추가한 컬럼들을 엔티티에 매핑할 수 없음

따라서 연결 테이블을 아예 엔티티로 만드는 방법이 있음(MemberProduct)

  • 회원상품(MemberProduct)엔티티와 회원, 상품을 각각 다대일 관계로 매핑
  • 회원과 상품 쪽에는 mappedBy 사용하여 양방향을 만들거나 아예 연관관계를 맺어주지 않는 것을 선택할 수 있음
  • 만약 기존 연결 테이블처럼 MEMBER_IDPRODUCT_ID를 복합키로 하는 기본 키를 사용하려면 @IdClass를 사용해야 함
@Entity
@IdClass(MemberProductId.class)
public class MemberProduct {
    @Id
    @ManyToOne
    @JoinColumn(name = "MEMBER_ID")
    private Member member;

    @Id
    @ManyToOne
    @JoinColumn(name = "PRODUCT_ID")
    private Product product;

    ...
}
public class MemberProductId implements Serializable {
    private String member;
    private String product;

    // equals and hashcode...
}
  • @IdClass에는 복합키로 사용할 식별자 클래스를 만들어서 매핑해 줌
    • 식별자 클래스는 Serializable을 구현해야 함
    • 식별자 클래스의 속성명과 엔티티에서 사용하는 식별자의 속성명이 같아야 함
    • equals, hashcode를 오버라이딩 해야 함
    • 기본 생성자가 있어야 함
    • public이어야 함
    • @IdClass대신 @EmbeddedId를 사용할 수 있음
  • 복합 키는 사용하기에 복잡하고 클래스를 새로 만들어야 함
  • 또한 연결 테이블의 식별자가 다른 두 테이블에 종속적이 됨
  • 그냥 데이터베이스에서 만들어주는 대리 키를 기본 키로 사용하자
    • 회원, 상품에서 가져온 식별자는 외래 키로만 사용
    • 기본 키를 복합 키에서 대리 키로 바꾸더라도 기존 회원, 상품 엔티티에는 변화가 없음
    • 이 경우에 연결 엔티티는 자체적인 id까지 가지므로 회원상품(MemberProduct)보다는 주문(Orders)이 더 적절한 네이밍이 됨

섹션 7. 고급 매핑

상속 관계 매핑

관계형 데이터베이스에는 상속이라는 개념이 없지만 슈퍼타입 - 서브타입 관계라는 유사한 모델링 기법이 존재

슈퍼타입 - 서브타입 관계는 논리 모델로, 물리 모델인 테이블로 구현 시 전략을 선택

  • 각각의 테이블로 변환(조인 전략)
  • 통합 테이블로 변환(단일 테이블 전략)
  • 서브타입 테이블로 변환(구현 클래스마다 테이블 전략)

조인 전략

엔티티 각각을 모두 테이블로 만들고 자식 테이블이 부모 테이블의 기본 키를 받아서 기본 키 + 외래 키로 사용

  • 조회할 때 조인을 사용하므로 조인 전략
  • 데이터베이스에는 타입이라는 개념이 없으므로 타입을 구분하는 컬럼이 필요
  • 부모 엔티티(슈퍼타입)에 @Inheritance(strategy = InheritanceType.JOINED 어노테이션과 @DiscriminatorColumn(name = {타입 구분 컬럼명}) 어노테이션을 사용
    • 기본값이 DTYPE이므로 실제 테이블의 타입 구분 컬럼명이 DTYPE이면 name 생략 가능
    • 이는 JPA 표준 명세이며, 하이버네이트를 포함한 몇몇 구현체는 구분 컬럼 없이도 동작
  • 상속받은 엔티티(서브타입)에 @DiscriminatorValue({구분 컬럼에 입력할 값})을 사용
  • 자식 테이블은 부모 테이블의 ID 컬럼명을 그대로 사용
    • 기본 키 컬럼명을 변경하고 싶으면 엔티티에 @PrimaryKeyJoinColumn 사용

장점

  • 테이블이 정규화됨
  • 외래 키 참조 무결성 제약조건 활용 가능
  • 저장공간의 효율적인 사용

단점

  • 조회할 때 조인이 많이 사용되므로 성능 저하
  • 조회 쿼리가 복잡
  • 데이터 등록 시 INSERT SQL이 두 번 실행

단일 테이블 전략

테이블을 하나만 사용하며, 구분 컬럼(DTYPE)으로 어떤 자식 데이터가 저장되었는지 구분

  • 자식 엔티티가 매핑한 컬럼은 NOT NULL일 수 없음
    • 상식적으로, BOOK에 해당하는 값을 저장할 때 ALBUM에 해당하는 값은 NULL이 들어갈 수 밖에 없음
  • @Inheritance(strategy = InheritanceType.SINGLE_TABLE), @DiscriminatorColumn 사용
  • 구분 컬럼이 필수적으로 사용되어야 함
    • @DiscriminatorVlalue를 지정하지 않으면 엔티티 이름을 사용

장점

  • 조인이 필요 없어서 일반적으로 조회 성능이 빠름
  • 조회 쿼리가 단순

단점

  • 자식 엔티티가 매핑하는 컬럼은 NOT NULL 불가
  • 테이블이 커질 수 있음 → 경우에 따라 조회 성능이 오히려 느릴 수 있음

구현 클래스마다 테이블 전략

자식 엔티티마다 테이블을 만들고 각각에 필요한 컬럼이 모두 있는 전략

  • 슈퍼타입에 해당하는 테이블이 없음
    • 부모 엔티티에 설정한 공통 필드가 각각의 테이블에 전부 들어가 있음
  • 구분 컬럼을 사용하지 않음
  • 일반적으로 비추천

장점

  • 서브타입 구분에 효과적
  • NOT NULL 사용 가능

단점

  • SQL에 UNION을 사용해야 하므로 여러 자식 테이블을 함께 조회 시 성능 저하
  • 자식 테이블을 통합한 쿼리가 어려움

@MappedSuperclass

부모 클래스는 테이블과 매핑하지 않고 자식 클래스에 상속 정보만 제공하고 싶을 때 사용

  • 여러 엔티티끼리 공통되는 필드가 있을 때 해당 필드를 하나로 추상화 하는 목적
  • 테이블은 상속받는 값을 포함해 각각 생성됨
    • 구현 클래스마다 테이블 전략과 비슷해 보이나, 슈퍼타입 - 서브타입 관계 용이 아님
  • 공통 매핑 정보를 정의한 부모 클래스에 @MappedSuperclass를 사용하고 자식 클래스에서 상속
    • 상속받은 매핑 정보를 재정의 하려면 @AttributeOverrides@AttributeOverride 사용
    • 상속받은 연관관계를 재정의 하려면 @AssociationOverrides@AssociationOverride 사용
  • @MappedSuperclass를 사용한 클래스는 엔티티가 아니므로 em.find나 JPQL에서 사용 x
    • 부모 클래스는 엔티티로 만들 일이 없으므로 추상 클래스가 적합

참고: 엔티티는 엔티티이거나 @MappedSuperclass로 지정한 클래스만 상속 가능

복합 키와 식별 관계 매핑

주의) 여기서 설명하는 부모 - 자식 테이블은 상속 관계가 아님. 기본 키를 내려받았음을 설명하기 위해 부모 - 자식으로 설명

식별 관계 vs 비식별 관계

  • 부모 테이블의 기본 키를 내려 받아서 자식 테이블의 기본 키 + 외래 키로 사용하면 식별 관계
  • 부모 테이블의 기본 키를 내려 받아서 자식 테이블의 외래 키로만 사용하면 비식별 관계
    • 외래 키에 NULL을 허용하지 않으면 필수적 비식별 관계
    • 외래 키에 NULL을 허용하면 선택적 비식별 관계
  • 최근에는 비식별 관계를 주로 사용하고 꼭 필요한 곳에만 식별 관계를 사용하는 추세

복합 키 - 비식별 관계

둘 이상의 @Id를 사용하려면 별도의 식별자 클래스를 만들어야 함

@IdClass를 사용해서 식별자 클래스와 매핑 가능

  • 다대다 매핑에서 이미 @IdClass의 조건 설명 함
  • 따로 식별자 클래스를 직접 생성하지 않고, em.persist를 호출하면 영속성 컨텍스트에 엔티티를 등록하기 전에 내부에서 식별자 클래스를 생성하고 영속성 컨텍스트의 키로 사용
  • 조회 시에는 식별자 클래스를 직접 만들어서 사용
  • 복합 키를 외래 키로 사용할 경우 @JoinColumns 사용
    • @JoinColumns 안에 @JoinColumn으로 각각의 외래 키 컬럼 매핑
    • @JoinColumn 안에는 referencedColumnName 속성 사용(JoinColumn의 name과 같으면 생략 가능)

@EmbeddedId도 사용 가능(조금 더 객체지향에 가까운 방법)

  • 엔티티에서 식별자 클래스를 직접 사용하고 해당 필드에 @EmbeddedId 어노테이션 붙여줌
    • 식별자 클래스는 @Embeddable 어노테이션을 붙여주어야 함
    • Serializable을 구현해야 함
    • equals, hashCode를 오버라이딩 해야 함
    • 기본 생성자가 있어야 함
    • public이어야 함
  • 엔티티 저장 시 식별자 클래스를 직접 만들어서 사용
  • 조회 시에도 식별자 클래스를 직접 만들어서 사용
  • 객체지향적이고 중복이 없어서 @IdClass보다 좋아보이지만 특정 상황에 JPQL이 좀 더 길어질 수 있음

참고

  • 복합 키에는 @GenerateValue 사용 불가능
  • 복합 키를 구성하는 컬럼에도 @GenerateValue 사용 불가능
  • 복합 키에는 equals hashCode를 필수적으로 오버라이딩 해야 하는데, 일반적으로 모든 필드를 사용
    • 왜 오버라이딩? 영속성 컨텍스트는 식별자 비교 시 동등성 비교 사용

복합 키 - 식별 관계

부모, 자식, 손자까지 계속 기본 키를 전달하는 식별 관계에서 자식 테이블은 부모 테이블의 기본 키를 포함해 복합키를 구성해야 함

  • @IdClass 사용 시
    // 부모
    @Entity
    public class Parent {
      @Id
      @Column(name = "PARENT_ID")
      private String id;
      private String name;
        ...
    }
    // 자식
    @Entity
    @IdClass(ChildId.class)
    public class Child {
      @Id
      @ManyToOne
      @JoinColumn(name = "PARENT_ID")
      public Parent parent;
      @Id
      @Column(name = "CHILD_ID")
      private String childId;
      private String name;
        ...
    }
    // 자식 ID
    public class ChildId implements Serializable{
        private String parent; // Child.parent 매핑
        private String childId; // Child.childId 매핑
        // equals, hashCode
        ...
    }
    // 손자
    @Entity
    @IdClass(GrandChildId.class)
    public class GrandChild {
        @Id
        @ManyToOne
        @JoinColumns({
                @JoinColumn(name = "PARENT_ID"),
                @JoinColumn(name = "CHILD_ID")
        })
        public Child child;
        @Id @Column(name = "GRANDCHILD_ID")
        private String id;
        private String name;
    }
    // 손자 ID
    public class GrandChildId implements Serializable{
        private ChildId child; // GrandChild.child 매핑
        private String id; // GrandChild.id 매핑
        // equals, hashCode
        ...
    }
    • 식별 관계는 기본 키와 외래 키를 같이 매핑
      • @Id@ManyToOne 같이 사용
  • @EmbeddedId 사용 시
    • @MapsId 사용해야 함

      // 부모
      @Entity
      public class Parent {
        @Id
        @Column(name = "PARENT_ID")
        private String id;
        private String name;
          ...
      }
      // 자식
      @Entity
      public class Child {
        @EmbeddedId
        private ChildId childId;
        @MapsId("parentId") // ChildId.parentId 매핑
        @ManyToOne
        @JoinColumn(name = "PARENT_ID")
        public Parent parent;
        private String name;
          ...
      }
      // 자식 ID
      @Embeddable
      public class ChildId implements Serializable {
          private String parentId; // @MapsId("parentId")로 매핑
          @Column(name = "CHILD_ID")
          private String id;
          //equals, hashCode
          ...
      }
      // 손자
      @Entity
      public class GrandChild {
          @EmbeddedId
          private GrandChildId id;
          @MapsId("childId") // GrandChildId.childId 매핑
          @ManyToOne
          @JoinColumns({
              @JoinColumn(name = "PARENT_ID"),
              @JoinColumn(name = "CHILD_ID")
          })
          public Child child;
          private String name;
          ...
      }
      // 손자 ID
      @Embeddable
      public class GrandChildId implements Serializable{
          private ChildId childId; // @MapsId("childId")로 매핑
          @Column(name = "GRANDCHILD_ID")
          private String id; //
          // equals, hashCode
          ...
      }
    • 식별 관계로 사용할 연관관계의 속성에 @Id 대신 @MapsId 사용

    • @MapsId는 외래 키와 매핑한 연관관계를 기본 키에도 매핑하겠다는 뜻

    • 속성 값으로 @EmbeddedId를 사용한 식별자 클래스의 기본 키 필드 지정

일대일 식별 관계

일대일 식별 관계는 자식 테이블의 기본 키 값으로 부모 테이블의 기본 키 값 사용

  • 부모 테이블 기본 키가 복합 키가 아니면 자식 테이블 기본 키를 복합 키로 구성하지 않아도 됨
  • @MapsId사용 시 속성 값을 비워둠

식별, 비식별 관계의 장단점

일반적으로 식별 관계 보다는 비식별 관계를 선호

  • 식별 관계는 부모 테이블의 기본 키를 자식 테이블로 전파하므로 자식 테이블의 기본 키 컬럼이 점점 늘어남
    • 조인할 때 SQL이 복잡해지고 기본 키 인덱스가 불필요하게 커짐
  • 식별 관계는 일대일 관계를 제외하고는 복합 기본 키를 만들어야 함
    • 별도의 복합 키 클래스를 만들어야 함
    • @GenerateValue 사용 불가능
  • 식별 관계 사용 시 기본 키로 자연 키를 조합하는 경우가 많은 반면, 비식별 관계 사용 시 대리 키를 주로 사용
    • 비즈니스 요구 사항은 언젠가 변하므로 대리 키가 좋음
  • 비식별 관계가 식별 관계에 비해 테이블 구조가 유연

식별 관계가 비교적 가지는 장점도 있음

  • 기본 키 인덱스를 활용하기 좋음
  • 특정 상황에서 조인 없이 하위 테이블만으로 검색 가능
    • 하위 테이블이 부모 테이블들의 기본 키를 가지고 있으므로

따라서 기본으로는 비식별 관계 + Long 타입의 대리 키를 사용하고 필요한 경우 식별 관계를 사용하는 것이 유리

선택적 비식별 관계는 NULL을 허용해서 OUTER JOIN을 사용해야 하므로 필수적 비식별 관계가 유리

조인 테이블

조인 테이블이라는 별도의 테이블을 사용해서 연관관계를 관리하는 방식

  • 연관관계가 추가되면 두 엔티티의 기본 키가 외래 키 값으로 조인 테이블에 매핑되는 형태
  • 엔티티에는 외래 키 컬럼이 없음
  • 선택적 비식별 관계의 단점을 해결할 수 있음
    • 외래 키에 NULL을 넣어두지 않고 연관관계를 맺을 때 조인 테이블에 값을 저장하면 되므로
  • 테이블을 추가해야 한다는 것이 가장 큰 단점
    • 기본은 조인 컬럼을 사용하고 필요할 경우 조인 테이블 사용
  • @JoinColumn 자리에 @JoinTable사용
  • 일대일 조인 테이블
    • 조인 테이블의 외래 키 컬럼 각각에 2개의 유니크 제약조건
  • 일대다, 다대일 조인 테이블
    • 다(N)와 관련된 컬럼에 유니크 제약조건(어차피 기본 키 지정에서 걸림)
  • 다대다 조인 테이블
    • 조인 테이블의 두 컬럼을 합해서 복합 유니크 제약 조건을 걸어야 함

엔티티 하나에 여러 테이블 매핑

@SecondaryTable을 사용해 한 엔티티에 여러 테이블을 매핑 가능

  • @SecondaryTable.name: 매핑할 다른 테이블의 이름
  • @SecondaryTable.pkJoinColumns: 매핑 할 다른 테이블의 기본 키 컬럼 속성
    • 다른 테이블에 매핑하려는 필드에는 @Column(table = {다른 테이블 이름}) 지정해 주어야 함. 지정하지 않으면 기본 테이블에 매핑됨
  • @SecondaryTables를 사용해 두 개 이상의 다른 테이블을 매핑 가능
  • 항상 두 테이블을 조회하므로 최적화가 어려워 비추천
    • 차라리 테이블 당 엔티티를 각각 만들어서 일대일 매핑을 권장
profile
Backend Developeer

0개의 댓글