Backend/Spring

[JPA] 값 타입 컬렉션 사용법 (@ElementCollection, @CollectionTable)

김룹 2024. 1. 26. 10:45

 

값 타입

int, String, Integer 처럼 단순히 값으로 사용하는 자바 기본 타입이나 객체.

 

 

 

값 타입 분류

  • 기본값 타입
    • 자바 기본 타입(int, double)
    • 래퍼 클래스(Integer, Long)
    • String
  • 임베디드 타입(Embedded type, 복합 값 타입)
  • 컬렉션 값 타입(Collection value type)

 

 

 

값 타입 컬렉션

값 타입을 컬렉션에 담아서 사용하는 것을 값 타입 컬렉션이라고 한다!

 

//기본 값 타입 컬렉션
List<String> stringList = new ArrayList()<>;

//임베디드 값 타입 컬렉션
Set<Address> addressSet = new HashSet<>();

 

위와 같이 데이터베이스 안에 값 타입 컬렉션을 저장하고 싶을 땐 어떻게 해야할까?

 

 

 

 

 

 

⚠️ 기본적으로 관계형 데이터베이스에는 컬렉션을 저장할 수 없다!

 

따라서 컬렉션을 저장하기 위해서는 별도의 테이블을 만들어서 컬렉션을 저장해야 함.

이때 사용하는 것이 @ElementCollection과 @CollectionTable 이다!

 

 

 

 

 

@ElementCollection

JPA가 컬렉션 객체임을 알 수 있게 한다.

엔티티가 아닌 값 타입, 임베디드 타입에 대한 테이블을 생성하고 1:N 관계로 다룬다.

 

 

 

@CollectionTable

값 타입 컬렉션을 매핑할 테이블에 대한 역할을 지정하는 데 사용한다

테이블의 이름과 조인정보를 적어줘야 함.

 

 

 

 

값타입 컬렉션의 제약사항

  • 값 타입은 Entity와 다르게 식별자 개념이 없다
  • 값은 변경하면 추적이 어렵다
  • 값타입 컬렉션에 변경 사항이 발생하면, 주인 Entity와 연관된 모든 데이터를 삭제하고, 값타입 컬렉션에 있는 현재 값을 모두 다시 저장한다.
  • 값 타입 컬렉션을 매핑하는 테이블은 모든 컬럼을 묶어서 기본 키를 구성해야함. Not Null, 중복 저장 안됨

 

 

🏷️ 복잡하다면 다르게 풀어야 한다. (값 타입 컬렉션 대안)

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

 

 

 

 

그렇다면 값타입은 언제 쓸까?

 

 

진짜 단순할 때,,, 치킨 피자를 select box로 만들어서 사용할 때..

 

 

 

 

정리

  • Entity 타입의 특징
    • 식별자 O (ID)
    • 생명주기 관리
    • 공유
  • 값 타입의 특징
    • 식별자 X (ID)
    • 생명주기를 Entity에 의존
    • 공유하지 않는 것이 안전하다 (복사하여 사용)
    • 불변 객체로 만드는 것이 안전하다
  • Entity와 값타입을 혼동해서 Entity를 값타입으로 만들면 안됨 !!! ⚠️
  • 식별자가 필요하고, 지속해서 값을 추적 및 변경해야 한다면 값타입이 아닌 Entity