Programming/JPA

[JPA] 값 타입 컬렉션 - 값 타입 (4)

soeun2537 2024. 7. 25. 07:51
해당 글은 김영한 님의 자바 ORM 표준 JPA 프로그래밍을 참고하여 작성한 글입니다.

 

 값 타입 컬렉션

값 타입을 하나 이상 저장할 때 List나 Set과 같은 Collection을 사용한다. 하지만 DB에는 Collection을 하나의 테이블에 저장할 수 없기 때문에 Collection을 저장하기 위한 별도의 테이블이 필요하다.

  • 방법: @ElementCollection, @CollectionTable

🔽 값 타입 컬렉션 코드

 @Entity
 public class Member {
    ...
    
    //값 타입 컬렉션
    @ElementCollection
    @CollectionTable(name = "ADDRESS",
                     joinColumns = @JoinColumn(name = "MEMBER_ID"))
    private List<Address> addressHistory = new ArrayList<>();
    ...
}
  • @ElementCollection: 값 타입 컬렉션을 사용하는 곳에 사용한다.
  • @CollectionTable: 추가 테이블을 매핑한다. 
    • @JoinColumns에는 FK로 쓸 값을 넣어주고 식별자는 모든 컬럼의 PK의 조합이 된다.
@CollectionTable을 생략하면 기본값을 사용해서 매핑한다. 기본값: <엔티티 이름>_<컬렉션 속성>

 

 값 타입 컬렉션 동작 방식

  • 지연 로딩을 사용한다.
  • 영속성 전이와 고아 객체 제거 기능을 필수로 가진다.

 

 값 타입 컬렉션의 제약사항

⚠️ 값은 변경하면 추적이 어렵다.

  • 값 타입은 Entity와 다르게 식별자 개념이 없다.
    • 따라서 값 타입 컬렉션에 변경 사항이 발생하면 주인 Entity와 연관된 모든 데이터를 삭제하고, 값 타입 컬렉션에 있는 현재 값을 모두 다시 저장한다.
  • 값 타입 컬렉션을 매핑하는 테이블은 모든 컬럼을 조합하여 기본 키를 구성해야 한다. (null 입력 및 중복 저장 불가능)

 

 값 타입 컬렉션 대안

⚠️ 위와 같은 제약상황 때문에 실무에서는 상황에 따라 값 타입 컬렉션 대신 일대다 관계를 고려해야 한다.

  • 일대다 관계를 위한 Entity를 만들고, 여기서 값 타입을 사용해서 영속성 전이 + 고아 객체 제거로 값 타입 컬렉션처럼 사용한다.

🔽 값 타입 컬렉션 대안 코드

@Entity
public class Member {
    ...
    
    //값 타입 컬렉션
    //@ElementCollection
    //@CollectionTable(name = "ADDRESS",
    //                 joinColumns = @JoinColumn(name = "MEMBER_ID"))
    //private List<Address> addressHistory = new ArrayList<>();
    
    //일대다 + 영속성 전이 + 고아 객체 제거 -> 값 타입 컬렉션"처럼"
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "MEMBER_ID")
    private List<Address> addressHistory = new ArrayList<>();
    
    ...
}

 

 

📍 참고