개발자꿈나무
갑 타입 - 임베디드 타입 본문
★ 임베디드 타입 (embedded type)
- 새로운 값 타입을 직접 정의할 수 있음
- 주로 기본 값 타입을 모아서 만들어서 복합 값 타입이라고도 함
- int, String과 같은 값 타입이라서 추적 불가능 + 엔티티가 삭제되면 자동으로 삭제됨
Member 엔티티 안에 근무 시작일, 근무 종료일, 주소의 도시, 지번, 우편번호 등의 속성이 들어간다면 이렇게 하나하나 나열하여 적을 것이다. 실제로 데이터베이스에 들어가는 모양 역시 이와 같을 것이다. 그러나 이 필드들을 크게 묶으면 기간과 주소라는 항목으로 묶일 것이다. 필드에 너무 많은 값들을 1:1로 나열해놓는 것보다 간단하게 기간, 주소로 적는 것이 깔끔한데 이 기간, 주소 등의 타입이 임베디드 타입이다.
public class Period {
private LocalDateTime startDate;
private LocalDateTime endDate;
}
public class Address {
@Column(name = "city") //가능
private String city;
private String street;
private String zipcode;
}
Period와 Address라는 클래스를 만들어 해당되는 값들을 적어주고 (@Column 등의 어노테이션 전부 가능하다) Member 엔티티에는 간단하게 private Period workPeriod; private Address homeAddress;를 적어준다. 다만 이렇게만 설정해주면 안되고 @Embeddable, @Embedded 어노테이션을 달아줘야 한다.
//기간
@Embedded
private Period workPeriod;
//주소
@Embedded
private Address homeAddress;
@Embeddable
public class Period {
...
}
@Embeddable
public class Address {
...
}
- 값 타입을 정의하는 곳은 @Embeddable, 값 타입을 사용하는 곳은 @Embedded를 사용한다. 둘 중 하나만 사용해도 상관없지만 이왕이면 둘 다 사용하는 것을 추천한다.
- 기본 생성자는 필수이다.
실행해보면 데이터베이스에는 변동사항 없이 모든 값들이 잘 들어가는 것을 확인할 수 있다.
★ 임베디드 타입의 장점과 특징
- 기간이나 주소 등의 타입은 꼭 회원 엔티티가 아니더라도 여러 군데에서 재사용할 수 있다.
- 응집도를 높이고, 필요에 따라 isWork() 메소드 등을 생성해서 사용할 수 있다.
- 임베디드 타입은 엔티티의 값일 뿐이며 임베디드 타입을 사용하기 전과 후에 매핑하는 테이블은 같다.
- 객체와 테이블을 아주 세밀하게 (find-grained) 매핑하는 것이 가능하다.
- 잘 설계한 ORM 애플리케이션은 매핑한 테이블의 수보다 클래스의 수가 더 많다.
- 임베디드 타입 역시도 연관관계를 가질 수 있으며 임베디드 타입 안에서 또다른 임베디드 타입을 가질 수 있다.
@Embedded
private Zipcode zipcode; //임베디드 타입 포함 가능
@ManyToOne
PhoneService provider; //연관관계를 가지는 엔티티 참조 가능
★ @AttributeOverride : 속성 재정의
만약 Member 엔티티에서 Address 타입을 중복해서 사용하고 싶으면 어떻게 해야할까?
@Embedded
private Address homeAddress;
@Embedded
private Address workAddress;
이렇게 임베디드 타입을 중복해서 실행하게 되면 이러한 오류가 발생한다.
Repeated column in mapping for entity
컬럼이 중복 매핑됐다는 뜻이다. 이럴 때에는 추가해서 사용하고자 하는 필드에 @AttributeOverrides를 이용해서 재정의 해주면 된다.
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "city", column = @Column(name = "WORK_CITY")), //name은 필드명
@AttributeOverride(name = "street", column = @Column(name = "WORK_STREET")),
@AttributeOverride(name = "zipcode", column = @Column(name = "WORK_ZIPCODE"))
})
private Address workAddress;
이렇게 실행을 하면 정상적으로 잘 동작하는 것을 확인할 수 있다.
'자바 > JPA' 카테고리의 다른 글
값 타입 컬렉션 (0) | 2023.08.28 |
---|---|
값 타입과 불변 객체 (0) | 2023.08.23 |
값 타입 - 기본 값 (0) | 2023.08.23 |
영속성 전이, 고아 객체 (0) | 2023.08.22 |
지연 로딩과 즉시 로딩 (0) | 2023.08.22 |