자바 ORM 표준 JPA 프로그래밍(인프런)

Ch09. 값 타입 - 값 타입 컬렉션

webmaster 2021. 12. 16. 11:59
728x90
  • 값 타입을 하나 이상 저장할 때 사용 
  • @ElementCollection, @CollectionTable 사용 
  • 데이터베이스는 컬렉션을 같은 테이블에 저장할 수 없다.
  • 컬렉션을 저장하기 위한 별도의 테이블이 필요함

값 타입 컬랙션 예제

값타입 컬랙션 사용 ( @CollectionTable)
FAVORITE_FOOD 테이블 
ADDRESS 테이블

Test

  • TEST

================Start============
Hibernate: 
    select
        member0_.MEMBER_ID as member_i1_6_0_,
        member0_.city as city2_6_0_,
        member0_.street as street3_6_0_,
        member0_.zipcode as zipcode4_6_0_,
        member0_.USERNAME as username5_6_0_ 
    from
        Member member0_ 
    where
        member0_.MEMBER_ID=?
Hibernate: 
    select
        addressesh0_.MEMBER_ID as member_i1_0_0_,
        addressesh0_.city as city2_0_0_,
        addressesh0_.street as street3_0_0_,
        addressesh0_.zipcode as zipcode4_0_0_ 
    from
        ADDRESS addressesh0_ 
    where
        addressesh0_.MEMBER_ID=?
address = old1
address = old2
Hibernate: 
    select
        favoritefo0_.MEMBER_ID as member_i1_4_0_,
        favoritefo0_.FOOD_NAME as food_nam2_4_0_ 
    from
        FAVORITE_FOOD favoritefo0_ 
    where
        favoritefo0_.MEMBER_ID=?
favoriteFood = 족발
favoriteFood = 치킨
favoriteFood = 피자
  • 값 타입 컬렉션도 지연 로딩 전략 사용 

값 타입 수정 예제 

값타입 수정 예제
old1만 제거하는것이 아닌 테이블 내용을 모두 지우고 다시 insert 한다.

  • 값 타입 컬렉션의 제약사항을 보면 알 수 있다.
  • 참고: 값 타입 컬렉션은 영속성 전에(Cascade) + 고아 객체 제거 기능을 필수로 가진다고 볼 수 있다

값 타입 컬렉션의 제약사항

  • 값 타입은 엔티티와 다르게 식별자 개념이 없다. 
  • 값은 변경하면 추적이 어렵다. 
  • 값 타입 컬렉션에 변경 사항이 발생하면, 주인 엔티티와 연관된 모든 데이터를 삭제하고, 값 타입 컬렉션에 있는 현재 값을 모두 다시 저장한다. 
    • 현업에서는 사용하면 안 된다는 뜻이다.
    • 테이블 자체가 문제이다(값이 바뀌면 추적이 불가능하기 때문)
  • 값 타입 컬렉션을 매핑하는 테이블은 모든 컬럼을 묶어서 기본키를 구성해야 함: null 입력 X, 중복 저장 X

값 타입 컬렉션 대안

값타입 컬렉션 대안

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

정리

  • 엔티티 타입의 특징 
    • 식별자 O 
    • 생명 주기 관리 
    • 공유
  • 값 타입의 특징
    • 식별자 X 
    • 생명 주기를 엔티티에 의존 
    • 공유하지 않는 것이 안전(복사해서 사용) 
    • 불변 객체로 만드는 것이 안전
  • 값 타입은 정말 값 타입이라 판단될 때만 사용
  • 엔티티와 값 타입을 혼동해서 엔티티를 값 타입으로 만들면 안 됨
  • 식별자가 필요하고, 지속해서 값을 추적, 변경해야 한다면 그것 은 값 타입이 아닌 엔티티
728x90