개발/Spring
JPA 복합키 @IdClass, @Embeddable
빨간머리 마녀 🍒
2023. 4. 25. 17:22
보통 Entity 선언시 프라이머리키를 하나로 선언하지만, 두개의 필드를 복합키로 함께 선언할 수도 있다.
복합키 생성 방식
복합키 생성 방식은 아래와 같이 두개로 나뉜다.
- @IdClass
- @EmbeddedId
복합키 생성 조건은 아래와 같다.
- 복합키는 무조건 public 이어야한다.
- no-arg constructor(인수가 없는 생성자)가 있어야한다.
- equals(), hashCode() 메서드 정의를 정의해야한다.
- Serializable 클래스를 상속해야한다.
@IdClass
// AccountId public 선언
public class AccountId implements Serializable {
private String accountNumber;
private String accountType;
// default constructor
public AccountId(String accountNumber, String accountType) {
this.accountNumber = accountNumber;
this.accountType = accountType;
}
// equals() and hashCode()
}
@Entity
// 엔티티에 IdClass 어노테이션으로 AccountId 연관짓기
@IdClass(AccountId.class)
public class Account {
@Id // 복합키를 구성하는 필드에 @Id 어노테이션 선언
private String accountNumber;
@Id
private String accountType;
// other fields, getters and setters
}
@EmbeddedId
// 복합키 클래스인 BookId에 @Embeddable 선언
@Embeddable
public class BookId implements Serializable {
private String title;
private String language;
// default constructor
public BookId(String title, String language) {
this.title = title;
this.language = language;
}
// getters, equals() and hashCode() methods
}
@Entity
public class Book {
@EmbeddedId // @EmbeddedId를 사용해 복합키 임베드
private BookId bookId;
// constructors, other fields, getters and setters
}
둘의 비교
- @IdClass의 경우 PK 필드를 두번 선언해줘야한다. (AccountId, Account) (↔ @EmbeddedId는 한번만 선언)
이는 아래와 같이 JPQL 쿼리를 작성할때 차이점을 만든다.
# @IdClass SELECT account.accountNumber FROM Account account
# @EmbeddedId SELECT book.bookId.title FROM Book book
- 복합키의 각 부분 Id를 각각 접근할 경우가 많을 경우 @IdClass가 유용하다.
- 복합키 전체를 하나로만 사용하는 경우가 많을 경우 @EmbeddedId가 선호된다.
→ @EmbeddedId의 경우 복합키를 단수 필드로 활용할 수 있고, 다른 테이블에서의 재사용이 가능하다.