본문 바로가기

SW 공부

[JPA] 복합키(Composite Key) 생성 및 관계 맺기

복합키 객체 생성

- 공통 : 엔티티 클래스의 PK 만을 속성으로 갖는 별도의 Composite Key 클래스가 있어야 한다.

- @EmbeddedId 방식 : Composite Key 클래스를 정의하고 entity 클래스 내부에 직접 사용

@Entity
data class TChild(
    @EmbeddedId
    var tChildIdL TChildId
) {
    val parentId
        get() = tChildIdL.parentId

    @MapsId("parentId")
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "parentId")
    lateinit var tParent: TParent
}

@Embeddable
data class TChildId(
    var parentId: Long = 0,
    var childId: Long = 0
) : Serializable

- @IdClass 방식 : Composite Key 클래스를 정의하고 entity 클래스 내부에는 PK 컬럼을 직접 사용하고 @id 로 매핑만 해줌

@Entity
@IdClass(TChildId::class)
data class TChild(
    @Id
    var parentId: Long,
    @Id
    var childId: Long
) {
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "parentId", referencedColumnName = "parentId", insertable = false, updatable = false)
    lateinit var tParent: TParent
}

data class TChildId(
    var parentId: Long = 0,
    var childId: Long = 0
) : Serializable

 

관계 맺기

@EmbeddedId 방식

- Composite Key 클래스를 직접 속성으로 사용하므로, 매핑관계를 이용하여 다른 엔티티를 입력/수정/삭제 할 수 있고 영속성 전이 등의 기능을 사용할 수 있다.

- @MapsId 를 이용하여 실제 key 의 속성을 알려주어야 한다.

- 실제 테이블 구조와 엔티티 구조가 달라 직관적이지 않고, 엔티티 생성자에 항상 Composite Key 객체를 넣어주어야 하는 번거로움이 있다.

- 복합키 안의 컬럼을 직접 사용하기 위해서는 별도의 get메소드가 필요하다. 위 예시에서는 getParentId() 메소드를 만들어서 embedded 된 id 클래스의 속성을 가져오도록 함

 

@IdClass 방식

- 엔티티 클래스의 속성으로 개별 key 를 가질수 있어서 직관적이고 단순함

- 다만, 속성값이 중복되므로 매핑된 다른 엔티티 객체는 insertable = false, updatable = false 으로 설정해야 한다. 따라서 매핑된 다른 엔티티를 직접 입력/수정/삭제는 할 수 없다.

 

[참고링크]

woowabros.github.io/experience/2019/01/04/composit-key-jpa.html

 

Legacy DB의 JPA Entity Mapping (복합키 매핑 편) - 우아한형제들 기술 블로그

안녕하세요. 우아한형제들에서 배달의민족 서비스의 광고시스템을 개발하고 있습니다. 시스템을 점진적으로 Spring Boot / JPA 기반으로 이관하면서 경험했던 내용을 공유하고자 합니다.

woowabros.github.io

http://blog.breakingthat.com/2018/03/16/jpa-entity-%EB%B3%B5%ED%95%A9pk-%EB%A7%B5%ED%95%91-embeddedid-idclass/

 

JPA-entity 복합PK 맵핑 (@EmbeddedId, @IdClass) - 조금 늦은, IT 관습 넘기 (JS.Kim)

먼저 기본 entity Class 외에 복합 기본키를 표현하기 위한 PK Class를 정의해야 한다. 그리고 PK Class는 아래의 조건을 만족해야한다. PK Class는 public이어야하고 public no-arg 생성자. property-based 접근이 사용될 경우, 해당 properties도 public or protected. implements equals 및 hashCode 메소드를 정의, 구현 해야한다.  해당

blog.breakingthat.com