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