JPA 복합키 - @IdClass, @EmbeddedId / @Embeddable, @MapsId

김승규·2024년 3월 1일

복합키

@IdClass

@Getter @Setter @ToString
@NoArgsConstructor
@IdClass(MyEntity.PK.class)
@Entity @Table(name = "my_entity")
public class MyEntity {
	@Id
    @Column(name = "pk_1", length = 50, nullable = false)
   	priavte String pk1;
   
	@Id
    @Column(name = "pk_2", nullable = false)
    priavte Integer pk2;
   
   // Other columns ...

    @AllArgsConstructor
    @NoArgsConstructor
    @Getter @Setter @ToString
    @EqualsAndHashCode
    public static class PK implements Serializable {
        private String pk1;
        private Integer pk2;
    }
}

PK의 필드와 Entity의 필드 명이 같아야 한다.

@EmbeddedId / @Embeddable

@Getter @Setter @ToString
@NoArgsConstructor
@Entity @Table(name = "my_entity")
public class MyEntity {
	@EmbeddedId
    private PK pk;
   
   // Other columns ...

    @AllArgsConstructor
    @NoArgsConstructor
    @Getter @Setter @ToString
    @EqualsAndHashCode
    @Embeddable
    public static class PK implements Serializable {
        @Column(name = "pk_1", length = 50, nullable = false)
   		priavte String pk1;
        
        @Column(name = "pk_2", nullable = false)
        priavte Integer pk2;
    }
}

외래키가 포함된 복합키

@IdClass + 외래키

@Getter @Setter @ToString
@NoArgsConstructor
@IdClass(MyEntity.PK.class)
@Entity @Table(name = "my_entity")
public class MyEntity {
	@Id
    @Column(name = "pk_1", length = 50, nullable = false)
   	priavte String pk1;
   
	@Id
    @ManyToOne
    @JoinColumn(name = "pk_2", nullable = false)
    priavte OtherEntity otherEntity;
   
   // Other columns ...

    @AllArgsConstructor
    @NoArgsConstructor
    @Getter @Setter @ToString
    @EqualsAndHashCode
    public static class PK implements Serializable {
        private String pk1;
        private Integer otherEntity;
    }
}

단, OtherEntity의 @Id가 Integer ohterEntity여야 한다.

@IdClass + 외래키 + @MapsId

만약, 사용하고 싶은 외래키의 필드 명은 pk지만, 조인 객체는 otherEntity로 접근하고 싶다면 @MapsId를 사용해야 한다.

@Getter @Setter @ToString
@NoArgsConstructor
@IdClass(MyEntity.PK.class)
@Entity @Table(name = "my_entity")
public class MyEntity {
	@Id
    @Column(name = "pk_1", length = 50, nullable = false)
   	priavte String pk1;
   
	@Id
    @Column(name = "pk_2", nullable = false)
    priavte Integer pk2;
    
    @MapsId("pk2")
    @ManyToOne
    @JoinColumn(name = "pk_2", nullable = false)
    private OtherEntity otherEntity;
   
   // Other columns ...

    @AllArgsConstructor
    @NoArgsConstructor
    @Getter @Setter @ToString
    @EqualsAndHashCode
    public static class PK implements Serializable {
        private String pk1;
        private Integer pk2;
    }
}

혹은 @EmbeddedId / @Embeddable 방식을 사용해도 된다.

@EmbeddedId / @Embeddable + 외래키 + @MapsId

@Getter @Setter @ToString
@NoArgsConstructor
@Entity @Table(name = "my_entity")
public class MyEntity {
	@EmbeddedId
    private PK pk;
    
    @MapsId("pk2")
    @ManyToOne
    @JoinColumn(name = "pk_2", nullable = false)
    private OtherEntity otherEntity;
   
   // Other columns ...

    @AllArgsConstructor
    @NoArgsConstructor
    @Getter @Setter @ToString
    @EqualsAndHashCode
    @Embeddable
    public static class PK implements Serializable {
        @Column(name = "pk_1", length = 50, nullable = false)
   		priavte String pk1;
        
        @Column(name = "pk_2", nullable = false)
        priavte Integer pk2;
    }
}
profile
꿈꾸는 리얼리스트 개발자 김승규입니다.

0개의 댓글