2022. 3. 26. 20:22ㆍJPA 기초
2-1) 기본 값 타입(primitive) - 이전 포스팅 참고
2-2) 임베디드 타입
임베디드 타입을 활용하면 새로운 값 타입을 직접 정의할 수 있다!!
int, String과 같은 값 타입이다. 주로 기본 값 타입을 모아 만들어서 복합 값 타입이라고도 한다.
ex) 회원 엔티티는 이름, 근무시작일, 근무 종료일, 주소 도시, 주소 번지, 주소 우편번호를 갖는다고 하자.
이 엔티티를 보면 근무 시작일-종료일 // 주소(도시, 번지, 우편번호) 묶고싶다는 생각이 들 것이다.
변경하면 회원 엔티티는 이름, 근무 기간, 집 주소를 갖는다. 임베디드 타입을 사용하면 이렇게 묶어낼 수 있다.
private LocalDateTime startDate;
private LocalDateTime endDate;
private String city;
private String street;
private String zipcode;
이전 코드의 경우 멤버라는 엔티티에 근무일, 집 주소가 흩어져 있다.
아래와 같이 변경 가능하다.
@Embedded
private Period workPeriod;
@Embedded
private Address homeAddress;
이후 Period, Address 클래스는
@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 String getCity() {
return city;
}
public String getStreet() {
return street;
}
public String getZipcode() {
return zipcode;
}
}
-사용법
@Embeddable: 값 타입을 정의하는 곳에 표시한다.
@Embedded: 값 타입을 사용하는 곳에 표시한다.
참고로 따로 뽑아낸 클래스에는 기본 생성자가 필수로 존재해야 한다.
강의에서 기본 생성자는 필수라고 하셨는데 이유는 모르겠다.. 검색해도 안나오네
기본 생성자 없이 코드를 실행시켰다.
INFO: HHH000182: No default (no-argument) constructor for class: hellojpa.Address (class must be instantiated by Interceptor)
다음과 같은 경고문이 떴고 쿼리문은 찍혀있지만, DB에는 아무런 변화가 없었다..
Hibernate 에서는 Reflection 으로 Entity Object 를 생성하기 때문에
모든 Entity 는 default constructor 를 갖고 있어야 하므로 저렇게 말씀하신 것 같다.
기본생성자의 주석을 풀고 실행하니 db에 반영되었다.
아무튼
이렇게 클래스로 따로 뽑아낸 경우
재사용이 가능하며(클래스로 뽑아냈으니) 클래스 내에 묶어놓았으니 응집도가 높다.
클래스 내에서 해당 값 타입만 사용하는 의미있는 메소드를 만들수 있으며
임베디드 타입을 포함한 모든 값 타입은, 값 타입을 소유한 엔티티에 생명주기를 의존한다는 장점이 있다.
* 임베디드 타입을 사용하기 전과 후에 매핑하는 테이블은 같다.
객체와 테이블을 세밀하게 매핑하는 것이 가능하다. 설계 시 모델링이 깔끔하게 떨어지고, 좀 더 객체지향적으로 코드를 작성할 수 있다!
잘 설계한 ORM 애플리케이션은 매핑한 테이블의 수 보다 클래스의 수가 더 많다고 한다.
만약 한 엔티티에서 같은 값 타입을 사용하면? 당연히 에러가 발생한다. 중복 매핑되었기 때문이다.
멤버라는 엔티티 내에서 아래처럼 같은 값 타입을 사용하면
@Embedded
private Address homeAddress;
@Embedded
private Address workAddress;
@Embedded
private Address homeAddress;
@Embedded
@AttributeOverrides({@AttributeOverride(name="city", column=@column("WORK_CITY"))}
private Address workAddress;
@AttributeOverrides를 사용해 컬럼 명 속성을 모두 재정의해야 한다. 위에서는 city만 재설정 하였으나
street, zipcode도 컬럼명을 재정의 해야 한다.
그렇게 하면 재정의된 테이블에 새로운 컬림이 생성되며 그 컬럼으로 insert문이 나간다.
'JPA 기초' 카테고리의 다른 글
JPQL 파라미터 바인딩, 프로젝션 (0) | 2022.03.28 |
---|---|
JPQL 기본 문법 (0) | 2022.03.28 |
JPA의 데이터 타입 - 값 타입, 엔티티 타입(4) (0) | 2022.03.26 |
JPA의 데이터 타입 - 값 타입, 엔티티 타입(3) (0) | 2022.03.26 |
JPA의 데이터 타입 - 값 타입, 엔티티 타입(1) (0) | 2022.03.26 |