단일키의 경우, PK가 1개 있는 경우를 말하며, 해당 키 값이 단일키가 된다.
=> 해당 값은 데이터를 구분할 수 있는 식별자가 된다.
복합키의 경우, PK 없이 FK 2개 이상으로 있는 경우를 말하며, 해당 키의 묶음이 복합키가 된다.
=> 해당 값은 데이터를 구분할 수 있는 식별자가 된다.
복합키를 사용할 엔티티 위에 @IdClass을 붙여주어 동작하는 방식이다.
@Entity
@IdClass(UserChannelId.class) // 어떤
public class UserChannel {
@Id
@ManyToOne
@JoinColumn(name = "user_id")
User user;
@Id
@ManyToOne
@JoinColumn(name = "channel_id")
Channel channel;
}
...
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class UserChannelId implements Serializable {
private Long user; // UserChannel 의 user 필드명과 동일해야 한다.
private Long channel; // UserChannel 의 channel 필드명과 동일해야한다.
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UserChannelId userChannelId = (UserChannelId) o;
return Objects.equals(getUser(), userChannelId.getUser()) && Objects.equals(getChannel(), userChannelId.getChannel());
}
@Override
public int hashCode() {
return Objects.hash(getUser(), getChannel());
}
}
@EmbeddedId을 통한 복합키 생성이다.
@Entity
public class UserChannel {
@EmbeddedId
private UserChannelId userChannelId;
@ManyToOne
@MapsId("user_id")
User user;
@ManyToOne
@MapsId("channel_id")
Channel channel;
}
...
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Embeddable
public class UserChannelId implements Serializable {
@Column(name = "user_id")
private Long userId;
@Column(name = "channel_id")
private Long channelId;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UserChannelId userChannelId = (UserChannelId) o;
return Objects.equals(getUser(), userChannelId.getUser()) && Objects.equals(getChannel(), userChannelId.getChannel());
}
@Override
public int hashCode() {
return Objects.hash(getUser(), getChannel());
}
}