[JPA] 값 타입 컬렉션

hi·2022년 10월 3일

@ElementCollection
@CollectionTable(name="테이블명")

  • 값 타입을 하나 이상 저장할 때 사용

  • 데이터베이스는 컬렉션을 같은 테이블에 저장 불가
    👉 일대다 개념이므로 컬렉션을 저장하기 위한 별도의 테이블 필요
    👉 조인하기 위한 키 필요

  • 값 타입은 엔티티와 다르게 식별자 개념이 없음
    식별자 개념을 넣으면 엔티티가 된다

  • 값은 변경하면 추적이 어려움

  • 값 타입 컬렉션을 매핑하는 테이블은 모든 컬럼을 묶어서 기본 키를 구성해야 함
    null 입력X , 중복 저장X

저장

  • .add()
    엔티티에 생명주기를 의존하기 때문에 따로 persist 하지 않음

조회

  • 컬렉션도 지연 로딩 사용
    @ElementCollection(fetch = FetchType.LAZY) 기본값

수정

  • Setter 사용 X

  • 통으로 교체해야 함
    .remove() 실행 후 .add()

  • 컬렉션은 대부분 대상을 찾을때 equals 사용
    👉 hashcode 구현 잘 되어있어야 함

  • 값 타입 컬렉션에 변경 사항이 발생하면, 주인 엔티티와 연관된 모든 데이터를 삭제하고 값 타입 컬렉션에 있는 현재 값을 모두 다시 저장
    (수정 데이터 하나를 삭제, 등록하는 것이 아닌 연관된 모든 데이터)
    👉 때문에 사용 X

  • 값 타입 컬렉션은 영속성 전이(Casecade) + 고아 객체 제거 기능을 필수로 가진다고 볼 수 있음

값 타입 컬렉션 대안

  • 실무에서는 상황에 따라 값 타입 컬렉션 대신 일대다 관계 고려
  • 일대다 관계를 위한 엔티티를 만들고, 여기에서 값 타입을 사용
  • 영속성 전이(Cascade) + 고아 객체 제거를 사용해서 값 타입 컬렉션 처럼 사용
ex)

//값 타입으로 매핑
@ElementCollection 
@CollectionTable(name = "ADDRESS", 
				 joinColumns = @JoinColumn(name = "MEMBER_ID"))
private List<Address> addressHistory = new ArrayList<>();

👇

//entity로 매핑
@OneToMany (cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "MEMBER_ID")
private List<AddressEntity> addressHistory = new ArrayList<>();

특징

엔티티 타입

  • 식별자 O
  • 생명 주기 관리
  • 공유

값 타입

  • 식별자 X
  • 생명 주기를 엔티티에 의존
  • 공유하지 않는 것이 안전 (복사하여 사용)
  • 불변 객체로 만드는 것이 안전

🔎 값 타입은 정말 값 타입이라 판단될 때만 사용한다 (아주 단순한 값)
식별자가 필요하고, 지속해서 값을 추적, 변경해야 한다면 그것은 값 타입이 아닌 엔티티

0개의 댓글