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에서 삭제된다.