Java/Spring Jpa

복합키 사용하기

move2 2023. 2. 1. 23:51

Spring jpa에서 복합키를 사용하기 위한 방법은 두가지가 있다.

1. @Idclass 사용

UserChannel.java

@Entity
@IdClass(UserChannelId.class)
public class UserChannel {
  ....

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

  @Id
  @ManyToOne
  @JoinColumn(name = "channel_id")
  Channel channel;
  ...
}

UserChannelId.java

@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());
  }
}

2. @EmbeddedId 사용

UserChannel.java

@Entity
public class UserChannel {

  @EmbeddedId
  private UserChannelId userChannelId;

 ...

  @ManyToOne
  @MapsId("user_id")
  User user;

  @ManyToOne
  @MapsId("channel_id")
  Channel channel;

 ...

}

UserChannelId.java

@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());
  }
}

다대다 관계에서 ManyToOne을 쓰지 않고 중간 매핑 테이블을 만들어 사용하는 예제인데, @EmbeddedId 방식이 더 편해보여, 다대다 관계를 맺을 일이 있으면 @EmbeddedId 방식의 복합키를 사용하는 매핑 테이블을 만들 것 같다.