본문 바로가기

카테고리 없음

TiL 복합키

💡 JPA에서 복합 기본키(Composite Primary Key) 매핑하기

 

좋아요(Favorite) 테이블은 다음과 같은 구조로 이루어짐:

  • 유저(User)의 기본 키
  • 산책 기록(Walk)의 기본 키

이 두 개의 컬럼을 조합하여 하나의 복합 기본 키로 사용해야 함.
이를 JPA에서는 다음의 2가지 방법으로 처리 가능

 

✅ 복합 기본키 매핑 방법 2가지

1. @IdClass 방식

관계형 데이터베이스(RDBMS)의 전통적인 방식에 가까움.

// 복합 키 클래스 정의
@NoArgsConstructor
@EqualsAndHashCode
public class FavoriteId implements Serializable {
    private Long user;
    private Long walk;
}

// Favorite Entity 정의
@Entity
@Getter
@IdClass(FavoriteId.class)
public class Favorite extends BaseEntity {

    @Id
    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;

    @Id
    @ManyToOne
    @JoinColumn(name = "walk_id")
    private Walk walk;
}

📌 사용 예

Favorite favorite = new Favorite();
favorite.setUser(user);
favorite.setWalk(walk);

User user = favorite.getUser();
Walk walk = favorite.getWalk();
 

2. @EmbeddedId 방식

보다 객체지향적인 방식. 복합키를 하나의 객체로 구성하여 엔티티에 포함시킴.

// 복합 키 클래스 정의
@NoArgsConstructor
@EqualsAndHashCode
@Embeddable
public class FavoriteId implements Serializable {
    private Long user;
    private Long walk;
}

// Favorite Entity 정의
@Entity
@Getter
public class Favorite extends BaseEntity {

    @EmbeddedId
    private FavoriteId favoriteId;

    @MapsId("user")
    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;

📌 사용 예

FavoriteId favoriteId = new FavoriteId(userId, walkId);
Favorite favorite = new Favorite();
favorite.setFavoriteId(favoriteId);

Long userId = favorite.getFavoriteId().getUser();
Long walkId = favorite.getFavoriteId().getWalk();

 

☑️ 두 방식의 공통점

조건설명
Serializable 복합키 클래스는 Serializable 인터페이스 구현 필요
기본 생성자 반드시 public 기본 생성자 있어야 함
equals(), hashCode() 필수 오버라이딩
접근 제어자 필드는 public 또는 접근 가능한 getter/setter 필요

🤔 어떤 방식이 더 적절할까?

상황추천 방식
엔티티 내부에서만 사용하는 단순한 구조 @EmbeddedId
복합 키가 재사용되거나 구조가 복잡 @IdClass

객체지향적으로 깔끔하게 묶고 싶다면 → @EmbeddedId
DB 설계에 더 밀접하고 복잡한 관계를 표현한다면 → @IdClass


💡 팁

팁 1: @EmbeddedId 사용할 때는 @MapsId를 반드시 써서 복합키 필드와 실제 관계를 연결해야 합니다.
팁 2: @IdClass를 사용할 경우, 복합 키 클래스에서 필드명과 타입은 엔티티의 @Id 필드와 정확히 일치해야 함.
팁 3: 복합 키 클래스는 JPA에서 엔티티로 간주하지 않으므로, @Entity는 쓰지 않아야 합니다.