Open emiling opened 2 years ago
@PrimaryKeyValueJoinColumn
를 사용한다// 상품 (부모 클래스)
@Entity
@Inheritence(strategy = Inheritance.JOINED)
@DiscriminatorColumn(name = "DTYPE")
abstract class Product(
@Id @GeneratedValue
@Column(name = "product_id")
val id: Long,
val name: String? = null,
val price: Int? = null
)
// 앨범 (자식 클래스)
@Entity
@DiscriminatorValue("A")
class Album(
val artist: String?
): Product
// 영화 (자식 클래스)
@Entity
@DiscriminatorValue("M")
class Movie(
val director: String?
val actor: String?
): Product
// 책 (자식 클래스)
@Entity
@DiscriminatorValue("B")
@PrimaryKeyValueJoinColumn(name = "book_id")
class Book(
val author: String?
val isbn: String?
): Product
// 상품 (부모 클래스)
@Entity
@Inheritence(strategy = Inheritance.SINGLE_TABLE)
@DiscriminatorColumn(name = "DTYPE")
abstract class Product(
@Id @GeneratedValue
@Column(name = "product_id")
val id: Long,
val name: String? = null,
val price: Int? = null
)
// 앨범 (자식 클래스)
// ... 위와 동일
// 영화 (자식 클래스)
// ... 위와 동일
// 책 (자식 클래스)
// ... 위와 동일
@Entity
@Inheritence(strategy = Inheritance.TABLE_PER_CLASS)
abstract class Product(
@Id @GeneratedValue
@Column(name = "product_id")
val id: Long,
val name: String? = null,
val price: Int? = null
)
// 앨범 (자식 클래스)
// ... 위와 동일
// 영화 (자식 클래스)
// ... 위와 동일
// 책 (자식 클래스)
// ... 위와 동일
not null
제약조건을 사용할 수 있다@MappedSuperClass
@Entity
는 실제 테이블에 매핑되지만 @MappedSuperClass
의 경우 실제 테이블과 매핑되지 않고 매핑 정보 상속을 위해 사용된다@MappedSuperClass
는 부모 클래스를 테이블과 매핑하지 않고 자식 클래스에게 매핑 정보만 제공하고 싶을 때 사용한다@Entity
와 달리, 실제 테이블과 매핑되지 않고 매핑 정보 상속을 위해 사용된다@MappedSuperclass
class BaseEntity(
@Id
@GeneratedValue
var id: Long = 0,
val name: String? = null
)
@Entity
data class User(
val email: String?
): BaseEntity()
@Entity
data class Seller(
val shopName: String?
): BaseEntity()
AttributeOverride
를 사용한다
@Entity
@AttributeOverrides(
AttributeOverride(name = "id", column = Column(name = "user_id")),
AttributeOverride(name = "name", column = Column(name = "user_name"))
)
data class User(val email: String?): BaseEntity() {}
@MappedSuperclass
로 지정한 클래스는 엔티티가 아니므로 em.find
나 JPQL 에서 사용 불가능하다 equals
와 hashCode
를 사용하여 동등성 비교를 하는데 @GeneratedValue
를 사용할 수 없으며 복합키를 구성하는 여러 컬럼 중 하나에도 사용할 수 없다
@Entity
@IdClass(ParentId::class)
data class Parent(
@Id
@Column("parent_id1")
val id1: String,
@Id
@Column("parent_id2")
val id2: String,
@Column("name")
val name: String
)
data class ParentId(
val id1: String,
val id2: String
) : Serializable
@Entity
data class Child(
@Id
val id: String,
@ManyToOne
@JoinColumns(
// 이렇게 두 컬럼이 동일하면 referencedColumnName 생략 가능
JoinColumn(name = "parent_id1", referencedColumnName = "parent_id1"),
JoinColumn(name = "parent_id2", referencedColumnName = "parent_id2")
)
val parent: Parent? = null
)
ParentId
를 따로 생성하지 않고 Product.id1과 Product.id2 를 넣어주고 em.persist
호출한다em.persist
를 호출하면 영속성 컨텍스트에 엔티티를 등록하기 직전에 ParentId 를 생성하고 영속성 컨텍스트의 키로 사용한다@Entity
data class Parent(
@EmbeddedId
val id: ParentId,
@Column(name = "name")
val name: String
)
@Embeddable
data class ParentId(
@Column(name = "parent_id1")
val id1: String,
@Column(name = "parent_id2")
val id2: String
) : Serializable
ParentId
를 직접 생성해준 뒤에 저장해야 하고, 조회 시에도 ParentId
식별자 클래스를 직접 사용한다@Id
와 @ManyToOne
을 같이 사용한다@Entity
data class Parent(
@Id @Column(name = "parent_id")
val id: String
)
@Entity
@IdClass(ChildId::class)
data class Child(
@Id
@ManyToOne
@JoinColumn(name = "parent_id")
val parent: Parent,
@Id @Column(name = "child_id")
val childId: String,
)
data class ChildId(
val parent: String, // Child.parent 매핑
val childId: String // Child.childId 매핑
) : Serializable
@Entity
@IdClass(GrandChildId::class)
data class GrandChild(
@Id
@ManyToOne
@JoinColumns(
JoinColumn(name = "parent_id"),
JoinColumn(name = "child_id"),
)
val child: Child,
@Id @Column(name = "grandchild_id")
val id: String,
)
@Embeddable
data class GrandChildId(
val child: ChildId, // GrandChild.child 매핑
val id: String // GrandChild.id 매핑
) : Serializable
@MapsId
를 사용하면 된다@Entity
data class Parent(
@Id @Column(name = "parent_id")
val id: String
)
@Entity
data class Child(
@MapsId("parentId")
@ManyToOne
@JoinColumn(name = "parent_id")
val parent: Parent,
@EmbeddedId
val childId: ChildId,
)
@Embeddable
data class ChildId(
val parentId: String,
@Column(name = "child_id")
val id: String
) : Serializable
@Entity
data class GrandChild(
@MapsId("childId")
@ManyToOne
@JoinColumns(
JoinColumn(name = "parent_id"),
JoinColumn(name = "child_id"),
)
val child: Child,
@EmbeddedId
val id: GrandChildId,
)
@Embeddable
data class GrandChildId(
val childId: ChildId,
@Column(name = "grandchild_id")
val id: String
) : Serializable
@Entity
data class Parent(
@Id @GeneratedValue
@Column(name = "parent_id")
val id: Long
)
@Entity
data class Child(
@Id @GeneratedValue
@Column(name = "parent_id")
val id: Long,
val name: String,
@ManyToOne
@JoinColumn(name = "parent_id")
val parent: Parent
)
@Entity
data class GrandChild(
@Id @GeneratedValue
@Column(name = "parent_id")
val id: Long,
@ManyToOne
@JoinColumn(name = "child_id")
val child: Child
)
@Entity
data class Board(
@Id @GeneratedValue
@Column(name = "board_id")
val id: Long,
val title: String,
@OneToOne(mappedBy = "board")
val boardDetail: BoardDetail
)
@Entity
data class BoardDetail(
@Id
val boardId: Long,
@MapsId // BoardDetail.boardId 매핑
@OneToOne
@JoinColumn(name = "board_id")
val board: Board,
val content: String?
)
JPA 고급 매핑
출처 : 자바 ORM 표준 JPA 프로그래밍 7장 JPA 시작(김영한 저)