JPA(Hibernate)에서 @Id 로 지정하는 건 엔티티를 고유하게 식별할 수 있는 단일 키를 의미한다.
근데 어떤 테이블은 하나의 컬럼만으로는 PK 를 못 만들고 여러 컬럼을 합쳐야 유일해지는 경우가 있다. 이때 복합키를 사용하게 된다.
"userGroupId + userId = 이 테이블의 기본키" 라는 사실을 JPA 에게 알려주기 위한 복합키를 담은 클래스라고 이해하면 된다.
@Entity 에서 각 컬럼에 @Id 를 붙이고 별도로 IdClass 식별자 클래스 선언 (implements Serializable 필수) 한다. IdClass 안에는 복합키를 구성하는 필드들을 정의 (userGroupId, userId) 해주면 된다.
JPA 가 내부적으로 equals(), hashCode() 를 이용해서 식별성을 비교한다.
JPA 는 엔티티의 식별성을 명확하게 알아야 한다.
단일 PK 는 그냥 @Id 하나면 끝이지만 컬럼 여러개를 합쳐야 유일해진다면 복합키를 사용하는 것이다. PK 가 여러개 일 때는 JPA 가 이 두개가 합쳐져야 같은 row 인 것을 알 수 있도록 별도의 키 묶음 클래스가 필요하다.
예를 들어
같은 그룹 안에 여러 userId 가 존재할 수 있고 같은 userId 가 다른 그룹에도 속할 수 있다. 그래서 user_group_mapping 테이블의 PK 가 user_group_id
, user_id
두개이고 한 줄을 구분할 때 두 컬럼을 합쳐야만 고유하게 식별할 수 있을거다. 이렇게.
(HANBADA, A1000000)
(HANBADA, A1000001)
(TAESAN, B2000001)
각각 다 다른 레코드다.
식별자 클래스를 @Embeddable 로 만들고 엔티티 안에서 @EmbeddedId 로 사용
조금 더 객체지향적인 코드가 된다.
필드 접근할 때 entity.getId().getUserGroupId() 처럼 한 단계 더 들어가야 하는 번거로움이 있다.