Spring
값 타입 컬렉션
yougeun
2023. 3. 27. 18:29
728x90
값 타입 컬렉션 사용
public class Member {
@Id @GeneratedValue
private Long id;
private String username;
private int age;
@ElementCollection
@CollectionTable(name = "FAVORITE_FOODS",joinColumns = @JoinColumn(name = "MEMBER_ID"))
@Column(name = "FOOD_NAME")
private Set<String> favoriteFoods = new HashSet<>();
@ElementCollection
@CollectionTable(name ="ADDRESS",joinColumns = @JoinColumn(name = "MEMBER_ID"))
private List<Address> addressHistory = new ArrayList<>();
...
}
데이터베이스는 컬렉션을 테이블에 저장할 수 없으므로 별도의 테이블을 만들어줘야 한다.
@ElementCollection어노테이션을 통해 값타입 컬렉션을 선언할 수 있다.
@CollectionTable어노테이션을 통해 테이블 네임과 FK를 설정할 수 있다.
예외적으로 Column명이 안 정해진 경우 @Column어노테이션을 통해 columnname을 지정해 줄 수 있다.
값타입 컬렉션은 소속된 Entity가 생명주기를 관리한다.(영속성전이(CACADE)와 고아객체를 필수로 가진다.)
지연로딩 전략을 기본으로 한다.
값 타입 컬렉션 수정
Member member = new Member();
member.setUsername("kim");
member.getFavoriteFoods().add("치킨");
member.getAddressHistory().add(new Address("old1","street1","zipcode1"));
member.getAddressHistory().add(new Address("old2","street2","zipcode2"));
em.persist(member);
em.flush();
em.clear();
Member findMember = em.find(Member.class,member.getId());
findMember.getAddressHistory().remove(new Address("old1","street1","zipcode1"));
findMember.getAddressHistory().add(new Address("new1","newStreet1","newZipcode1"));
(1) 값타입 컬렉션을 수정 시 컬렉션에 있는 값을 지우고 새로 넣어줘야 한다.
(2)값 타입 컬렉션에 변경 사항이 발생하면, 주인 엔티티와 연관된모든 데이터를 삭제하고, 값 타입 컬렉션에 있는 현재 값을 모두 다시 저장한다.
값 타입 컬렉션 제약사항
값 타입은 엔티티와 다르게 식별자가 없어 값을 변경하면 추적이 어렵다.
값 타입 컬렉션을 매핑하는 테이블은 모든 컬럼을 묶어서 기본키를 구성해야 해야한다. (null X, 중복 저장X)
값 타입 컬렉션 대안
실무에서는 상황에 따라 값타입 컬렉션 대신에 일대다 컬렉션을 고려하고
영속성전이(CASADE) + 고아객체제거를 사용해서 값타입 컬렉션처럼 사용해야한다.
식별자가 필요하고 지속해서 값을 추적하고 변경해야 한다면 엔티티로 만들어야 한다.
728x90