- Basic 타입: 기본형 및 Wrapper 타입, String - Embedded 타입: 복합 값 타입으로 별도의 클래스로 구성(ex: Address, Phone, Email, ...) - Collection 값 타입: 여러 가지 내용을 가지는 타입
Value 타입 중 Basic 타입이야 별 특별한 내용이 없고 여기서는 약간 생소한 Embedded 타입과 Collection에 대해 알아보자.
Embedded 타입
Embedded 타입
Embedded 타입이란 Entity의 속성 중 복합 값 타입으로 필요에 따라 생성한 사용자 정의 클래스를 말한다.
예를 들어 email을 id(String)와 domain(String)으로 구성할 때데이터베이스 차원에서는 이 둘을 구분해서별개의 컬럼으로 작성해야겠지만객체 입장에서는 Email이라는 새로운 객체 타입으로 관리하는 것이 일반적이다. 이때 이 둘을 하나로 묶어 만든 Email 타입을 Embedded 타입이라고 한다.
Embedded 타입의 작성
Embedded 타입을 만들기 위해서는 @Embedded 와 @Embeddable 애너테이션을 사용한다.
먼저 새롭게 정의하는 Embedded 타입에는@Embeddable을 사용한다.(이 클래스는 Embed 될 수 있다.!)
예를 들어 Member가 하나 이상의 Email을 포함한다면 어떨까? 회사에서 사용하는 공식 Email과 개인적으로 사용하는 Email이 있다고 생각해보자.
자바에서는 변수 명을 이용해서 처리할 수 있지만 데이터베이스 입장에서는 둘 다 동일한 이름의 테이블 컬럼이 필요하기 때문에 중복이 발생한다. 이때는 @MappedSuperclass와 마찬가지로 @AttributeOverride 또는 @AttributeOverrides를 사용할 수 있다.
하나 이상의 값 타입을 저장할 때는Collection을 이용할 수 있다. 예를 들어 Member가 가지고 있는 별명들을 저장하려면 하나의 컬럼에 여러 정보가 저정되어야 하는데 이는 제1정규화의 원칙인 도메인 원자값의 조건에 만족하지 않게 된다.
이때 값 타입의 Collection을 사용할 수 있다. (결국 별도의 테이블에 저장하고 join 해서 가져온다.)
@ElementCollection과 @CollectionTable
@ElementCollection은basic type이나 Embedded type의 Collection을 선언할 때 사용한다. 그리고 이 정보를 별도의테이블로 관리하기 위해서 @CollectionTable을 사용한다.
@ElementCollection은 '값을 언제 조회할 것인가?'에 대한 설정을 위한 fetch 속성을 가진다. 기본 값은 FetchType.LAZY이다.
FetchType에 대한 설명은 뒤에 다루기로 한다. 일단 LAZY는 실제 그 데이터가 사용되는 시점이고 다른 속성은 EAGER가 있다.
@Target( { METHOD, FIELD })
@Retention(RUNTIME)
public @interface ElementCollection {
FetchTypefetch() defaultFetchType.LAZY;
}
@CollectionTable에는 Collection 내용을 저장할 테이블을 설정한다. 주로 사용되는 속성은 name과 joinColumns인데 생략하면 기본 값으로 name은 "부모클래스이름_속성명" 이 사용되고 joinColumns에는 "속성명"이 사용된다. 어차피 이렇게 기본 값을 사용할 경우 @CollectionTable은 생략 할 수 있다.
Collection 내용이 저장될 테이블은 Entity에 종속적이다. 따라서 Entity가 삭제될 경우 컬렉션 테이블의 내용도 자동으로 삭제된다.(내부적으로 CascadeType.ALL이 적용된다.)
@Target( { METHOD, FIELD })@Retention(RUNTIME)public@interface CollectionTable {
String name() default ""; // 연결하려는 테이블 이름
JoinColumn[] joinColumns() default {}; // join에 사용될 부모 테이블의 join 컬럼 이름
...
}