새로운 값 타입을 직접 정의할 수 있다.
JPA는 그러한 값 타입을 임베디드 타입이라고 한다.
주로 기본 값 타입을 모아서 만들기 때문에 복합 값 타입이라고도 한다.
int, String과 같은 값 타입
근무 시작일, 근무 종료일과 도시, 우편 번호, 주소는 공통으로 묶을 수 있는 데이터이다.
공통으로 묶을 수 있는 데이터를 Period
Address
값 타입으로 정의한다.
@Embeddable
: 값 타입을 정의하는 곳에 표시@Embedded
: 값 타입을 이용하는 곳에 표시재사용이 가능한다.
-> 기간이나 주소는 시스템 전체에서 이용할 수 있는 데이터이다.
응집도가 높다.
-> Period.isWork()
처럼 해당 값 타입만 이용하는 의미있는 메서드를 만들 수 있다.
임베디드 타입을 포함한 모든 값 타입은, 값 타입을 소유한 엔티티에 생명주기를 의존한다.
@Entity
public class Member {
...
// 임베디드 타입
@Embedded
private Period period;
// 임베디드 타입
@Embedded
private Address address;
// 응집성 있는 로직 구현
public boolean isWork() {
return true;
}
...
}
@Embeddable
public class Period {
private LocalDateTime startDate;
private LocalDateTime endDate;
//기본 생성자 필수
public Period(){
}
public period(LocalDateTime startDate, LocalDateTime endDate) {
this.startDate = startDate;
this.endDate = endDate;
}
}
@Embeddable
public class Address {
private String city;
private String street;
private String zipcode;
// 기본 생성자 필수
public Address() {
}
public Address(String city, String street, String zipcode) {
this.city = city;
this.street = street;
this.zipcode = zipcode;
}
}
public class JpaMain {
public static void main(String[] args) {
Member member = new Member();
member.setUsername("name");
member.setAddress(new Address("city", "street", "10001"));
member.setPeriod(new Period());
em.persist(member);
tx.commit();
}
}
임베디드 타입은 엔티티의 값일 뿐이다.
임베디드 타입을 사용하기 전과 후에 매핑하는 테이블은 같다.
객체와 테이블을 아주 세밀하게(find-grained) 매핑하는 것이 가능하다.
잘 설계한 ORM 애플리케이션은 매핑한 테이블의 수보다 클래스의 수가 더 많다.
한 엔티티에서 같은 값 타입을 사용할때 이용한다.
@Entity
public class Member {
@Id
@GeneratedValue
private Long id;
@Column(name = "name")
private String username;
@Embedded
private Period period;
// 같은 임베디드 타입을 중복해서 사용할 경우 에러가 난다.
@Embedded
private Address homeAddress;
@Embedded
private Address workAddress;
}
같은 임베디드 값 타입을 중복해서 사용할 경우 에러가 난다.
이 때 @AttributeOverride
어노테이션을 이용해 새로운 컬럼 명을 정의해준다.
@Entity
public class Member {
@Id
@GeneratedValue
private Long id;
@Column(name = "name")
private String username;
@Embedded
private Period period;
@Embedded
private Address homeAddress;
// Column 이름 재정의
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "city", column = @Column(name = "work_city")),
@AttributeOverride(name = "street", column = @Column(name = "work_street")),
@AttributeOverride(name = "zipcode", column = @Column(name = "work_zipcode"))
})
private Address workAddress;
}
period
가 null이면 그 안에 있는 StartDate
, EndDate
모두 null이다.참고 :
김영한. 『자바 ORM 표준 JPA 프로그래밍』. 에이콘, 2015.