본문 바로가기
TIL

내일배움캠프 6주차 Spring 관계의 종류, 영속성 전이 등

by 율량동박씨 2024. 5. 22.

오늘의 키워드

  • 관계
  • 영속성 전이
  • 고아 Entity 삭제

오늘의 내용

  • 1 대 1 관계
    • @OneToOne 애너테이션을 이용해 1대 1 관계를 맺어준다
    • 외래 키의 주인을 직접 지정해야하고 외래 키의 주인은 등록, 수정, 삭제가 가능하며 주인이 아닌 쪽은 외래 키 읽기만 가능하다
    • 단방향 관계
      • @JoinColumn()은 외래 키의 주인이 활용하는 애너테이션이고 컬럼명, null여부, unique여부를 지정할 수 있다. 단방향의 경우 @JoinColumn()만 사용하면 된다
      • @JoinColumn()을 생략해도 디폴트 옵션이 적용되는데 1대N의 관계에서는 생략하면 JPA가 외래 키를 저장할 컬럼을 파악하지 못해 의도치 않은 중간 테이블이 생성되어 반드시 설정해 주는 게 좋다
    • 양방향 관계
      • 양방향 관계에서 외래 키의 주인을 지정할 때 @JoinColumn()의 mappedBy옵션을 외래 키 주인이 아닌 곳에 지정해야 한다
      • 상대 Entity는 외래 키의 주인 필드를 가지면서 mappedBy옵션을 사용해 속성 값으로 외래 키의 주인 Entity에 선언된 @JoinColumn()으로 설정되고 있는 필드명을 넣어줘야 한다
      • 양방향 관계에서는 mappedBy 옵션을 생략하면 단방향처럼 의도치 않은 중간 테이블이 생성되어 반드시 설정해야 한다
  • N 대 1 관계
    • @ManyToOne를 사용해 N대1관계를 설정한다
  • 1 대 N 관계
    • @OneToMany를 사용해 1:N의 관계를 설정한다
    • 외래 키를 주인이 직접 가질 수 있다면 INSERT발생 시 한 번에 처리할 수 있지만 실제 DB에서 외래 키를 주인이 아닌 쪽이 가지고 있기 때문에 추가적인 UPDATE가 발생된다는 단점이 존재한다.
    • 양방향 관계는 존재하지 않지만 억지로 설정은 가능하다
  • N 대 M 관계
    • @ManyToMany를 사용해 N:M 관계를 설정한다.
    • JPA에 의해 중간 테이블이 자동 생성되는데 이를 방지하기 위해 외래 키를 가진 중간 테이블을 직접 생성하면 컨트롤을 하기 쉬워진다
  • 지연 로딩과 즉시 로딩
    • JPA는 연관관계가 설정된 Entity의 정보를 바로 가져올지 필요할 때 가져올 수 있는데 이때 FetchType을 사용해 결정할 수 있다
      • FetchType.LAZY : 지연 로딩으로 필요한 시점에 정보를 가져온다
      • FetchType.EAGER : 즉시 로딩으로 조회할 때 연관된 모든 Entity의 정보를 즉시 가져온다
    • 연관관계에서 기본값을 구분할 수 있는데 이는 애너테이션 이름뒤에 Many가 붙으면 효율을 위해 지연 로딩이 기본값이고 One이 붙으면 즉시 로딩이 기본값이 된다
  • 영속성 전이
    • 영속 상태의 Entity에서 수행되는 작업들이 연관된 Entity까지 전파되는 상황을 말한다
    • 영속성 전이를 적용해 해당 Entity를 저장할 때 연관된 Entity까지 자동으로 저장하기 위해서는 자동으로 저장하려고 하는 Entity에 추가한 연관관계 애너테이션에 CASCADE:PERSIST옵션을 설정하면 된다
    • CASCADE:REMOVE는 연관된 Entity와의 관계를 삭제하는 옵션이다
    • cascade = {CascadeType. PERSIST , CascadeType. REMOVE } 이런 식으로 중복옵션을 설정할 수도 있다
  • 고아 Entity 삭제
    • orphanRemoval
      • CASCADE:REMOVE 옵션의 경우 연관된 Entity와 관계를 삭제했다고 자동으로 Entity까지 삭제가 되지 않아 사용되는 옵션이다
      • orphanRemoval, CASCADE:REMOVE 옵션을 사용할 때 삭제하려고하는 연관된 Entity를 다른 곳에서 참조하고 잇는지 아닌지를 꼭 확인해야 한다
      • ManyToOne이 설정된 Entity는 해당 Entity객체를 참조하는 다른 객체들이 있을 수 있어 orphanRemoval옵션을 가지고 있지 않다

오늘의 회고

  • 이번 주 중으로 최대한 강의를 들어야 다음 주에 온전히 프로젝트에 매진할 수 있을거 같아서 강의를 듣는 중인데 듣다 보면 TIL 작성을 못 할 거 같아 미리 작성했다
  • 강의를 진행하다가 분명 똑같이 작성한 코드인데 예외가 발생해서 한시간을 넘게 씨름을 했는데 아래 코드에서 ProductResponseDto에서 ProductRequestDto로 잘못 입력해서 발생했던 거였다. 같이 잘못된 점을 찾아주신 모든 분께 감사인사를 여기에라도 전한다
public ProductResponseDto createProduct(@RequestBody ProductRequestDto requestDto, @AuthenticationPrincipal UserDetailsImpl userDetails) {
    return productService.createProduct(requestDto, userDetails.getUser());
}