엔티티가 아닌 값 타입에 대한 컬렉션을 데이터베이스에 저장하는 방법을 알아볼 것이다.
1. 값 타입 컬렉션 매핑
- 값 타입 컬렉션 필드에 @ElementCollection, @CollectionTable 어노테이션을 추가해서 사용하면 된다.
- DB 테이블은 컬럼 값으로 컬렉션을 가질 수 없기 때문에 별도의 테이블을 만들어야 한다.
예시
- Member.class의 일부 필드다.
@ElementCollection
@CollectionTable(name="FAVORITE_ANIMALS",
joinColumns=@Joincolumn(name="MEMBER_ID"))
@Column(name="ANIMAL_NAME") // 동물 정보 필드의 이름을 결정
private Set<String> favoriteAnimals = new HashSet<String>(); // String 타입
@ElementCollection
@CollectionTable(name="ADDRESS",
joinColumns=@Joincolumn(name="MEMBER_ID"))
private List<Address> addressHistory = new ArrayList<Address>(); // 임베디드 타입
※ @CollectionTable을 생략하면 기본 이름으로 매핑된다.
2. 값 타입 컬렉션 사용
- 값 타입 컬렉션은 영속성 전이와 고아 객체 제거 기능을 가지기 때문에 엔티티만 영속화하면 된다.
- 값 타입은 equals(), hashcode() 메소드를 구현해서 동일한 레코드는 JPA가 같은 객체로 인지하도록 하자.
예시
Member member = new Member();
// ...
member.getFavoriteAnimals().add("Dog");
member.getFavoriteAnimals().add("Cat");
member.getFavoriteAnimals().add("Hamster");
member.getAddressHistory().add(new Address("서울", "강북", "123-456"));
member.getAddressHistory().add(new Address("대전", "중구", "135-790"));
em.persist(member);
3. 값 타입 컬렉션 사용 시에 주의 사항
- 값 타입 컬렉션에 있는 값 타입들은 별도의 테이블에 저장된다고 앞서 언급했다. 만약 값 타입 컬렉션에 변경 사항이 발생하면, 이 테이블에서 값 타입 컬렉션과 연관된 데이터를 모두 삭제 한 뒤에 현재 값 타입 컬렉션에 있는 모든 값을 다시 저장한다. 왜냐하면, 값 타입의 값이 변경되면 DB에 있는 원본 데이터를 찾기 어렵기 때문이다. 따라서, 값 타입 컬렉션이 매핑된 테이블에 데이터가 많다면 값 타입 컬렉션 대신에 일대다 관계를 생성하는 것이 더 효율적이다.
- 값 타입 컬렉션을 매핑하는 테이블은 모든 컬럼을 묶어서 기본 키를 구성하기 때문에, 기본 키 제약 조건으로 인해 컬럼에 null을 입력하거나 같은 값을 중복해서 저장할 수 없다.
● 참고자료 : 자바 ORM 표준 JPA 프로그래밍
'Spring 사전 준비 > JPA Hibernate' 카테고리의 다른 글
[JPA] QueryDSL (0) | 2022.08.10 |
---|---|
[JPA] JPQL의 작성 (0) | 2022.08.04 |
[JPA] 복합 값 타입과 불변 객체 (0) | 2022.08.03 |
[JPA] CASCADE 기능 (0) | 2022.08.03 |
[JPA] 즉시 로딩과 지연 로딩 (0) | 2022.08.01 |
댓글