⭐알게 된 점⭐

👉 복합키 사용하기

- PK 없이 FK 2개를 사용하는 방법

- 선언 방법

1. @IdClass 활용

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

---------------------------------------------------------------------------------------

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

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

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

 

2. @EmbeddeId 활용

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

 

👉 영속성 전이(Cascade) + 고아 객체 제거(orphanRemoval)

Cascade

- @OneToMany 혹은 @OneToOne에서 사용

- 양쪽 엔티티의 라이프 사이클이 동일하거나 비슷해야함

- 대상 엔티티로의 영속성 전이는 현재 엔티티에서만 전이 되어야 함

orphanRemoval

- @OneToMany 혹은 @OneToOne에서 사용

- Cascade.REMOVE와 비슷한 용도로 쓰임

- 부모 객체에서 리스트 요소 삭제 했을 경우 해당 자식 객체는 매핑 정보가 없어지므로 대신 삭제

영속성 전이 최강 조합 : orphanRemoval=true + Cascade.ALL

-> 두개를 함께 설정하면 자식 엔티티의 라이프 사이클이 부모 엔티티와 동일해지며, 직접 자식 엔티티의 생명주기를 관리할 수 있게 되므로 자식 엔티티의 Repository가 필요가 없어짐

 

👉 QueryDSL

- QueryDSL의 Predict 인터페이스로 조건문을 여러개 구성하여 따로 관리할 수 있음

- findOne(Predict), findAll(Predict) 이 메서드가 주로 사용됨

- Join이 필요한 쿼리일 경우 사용할 수 없음


🐰 END

JPA 심화 강의를 수강하는데 계획했던 것보다 시간이 좀 더 필요할 것 같다!

BELATED ARTICLES

more