[JPA] 컬렉션 값타입

김형진·2023년 5월 30일
0

JPA의 Embedded를 사용하면 엔티티가 포함하는 객체를 하나의 테이블에 저장할 수 있다.

예를 들어, Member엔티티가 Address라는 객체를 포함하는 경우 Address에 임베디드 설정만 해줘도 address의 필드들이 member테이블에 컬럼으로 같이 저장된다.

@Entity
public class Member{
	
    private Long id;
    private String name;
    private String city;
    private String street;
    private String zipcode;
    
}

에서

@Entity
public class Member{
	
    private Long id;
    private String name;
    @Embedded private Address address;
    
}

@Embeddable
public class Address {

	private String city;
    private String street;
    private String zipcode;
}

로 코드를 객체지향적으로 변경하면서 Db의 스키마는 건들지 않을 수 있었다.

엔티티가 컬렉션을 포함하는 경우엔 @ElementCollection, @CollectionTable(생략가능) 어노테이션을 사용하여 컬렉션 값타입용 테이블을 하나 생성하여 Member타입을 참조하게 된다.

예를 들어

@Entity
public class Member {
	
    private List<Address> addressHistory;
    
}

라는 필드가 있다면, AddressHistory테이블이 생성되고, Member의 id를 참조하는 컬럼과 String을 담는 address 관련 컬럼들이 생기게 될 것이다.

단, 컬렉션 테이블의 경우 식별자가 없으므로 Member의 컬렉션에 변경사항이 생긴 경우, member id를 참조하는 row를 전부 삭제한 뒤 새로 insert한다.

컬렉션 내의 내용이 많아지는 경우 컬렉션 변경마다 많은 delete와 insert가 발생하기 때문에 이 같은 경우에는 컬렉션 값타입을 Entity로 설정하여 식별자를 가지게 하고 영속성 전이와 고아객체 설정을 통해 엔티티를 값타입처럼 사용하는 것이 좋다.

@Entity
public class Member {
	
    @OneToMany(cascade = CascadeType.ALL, orphanRemocval = true)
    @JoinColumn(name = "MEMBER_ID")
    private List<AddressEntity> addressHistory;
    
}

@Entity
public class AddressEntity {

	@Id @GeneratedValue
    private Long id;
    @Embedded private Address address;
}

영속성 전이로 인해 Member객체가 영속화되거나 삭제되면 addressHistory로 따라 영속화 혹은 삭제되며, Member객체로부터의 참조가 끊기면 DB에서 삭제된다.

profile
히히

0개의 댓글