3. Embeddable
Aggregate Mapping
OOP에선 의미가 드러나지 않는 Primitive Type 대신 Value Object를 활용하는걸 권하는데 JPA에서는 Aggregate Mapping을 통해 이를 지원할 수 있다.
예를 들어 Person객체가 있고 필드로 name, age, gender를 갖는다고 해보자.
각 필드의 타입을 String으로 가져간다면 필드의 특성을 반영하기 힘들다. Gender타입을 선언해 gender를 사용해보자.
기존의 객체 생성이 다음과 같았다면
Embeddable 어노테이션을 정적 팩토리 메서드를 사용하면 다음과 같이 명시적으로 선언이 가능하다.
이런 식으로 하나의 Value Object를 만들어서 Gender에 대한 모든 처리를 위임했을 때 Person 객체가 SRP를 따르고 단순해질 거란 것 알 수 있다.
Value Object
값 타입
JPA의 데이터 타입은 엔티티 타입과 값 타입으로 나눌 수 있는데 엔티티 타입은 @Entity로 정의하는 객체이고 값 타입은 int, Integer, String처럼 단순히 값으로 사용하는 자바 기본 타입이나 객체를 말한다. 엔티티 타입은 식별자를 통해 추적 가능하지만 값 타입은 식별자가 없고 숫자나 문가탕느 속성만 있어 추적할 수 없다.
값 타입은 3가지로 나눌 수 있다.
기본값 타입
자바 기본 타입(int, double)
래퍼 클래스(Integer)
String
임베디드 타입(복합 값 타입) 새로운 값 타입을 직접 정의해서 사용할 수 있는데 이것을 임베디드 타입이라 한다.
임베디드 타입은 기본 생성자가 필수다
임베디드 타입을 사용하기 전과 후에 매핑하는 테이블은 같다
컬렉션 값 타입
@Entity
JPA를 사용해서 테이블과 매핑할 클래스는 @Entity 어노테이션을 필수로 붙여야 한다.
속성
주의 사항은
기본 생성자는 필수로 만들어줘야 한다.(파라미터가 없는 public 또는 protected 생성자)
final클래스, enum, interface, inner클래스에는 사용할 수 없다.
저장할 필드에 final을 사용하면 안된다.
@Table
엔티티와 매핑할 테이블을 지정한다. 생략하면 매핑한 엔티티 이름을 테이블 이름으로 사용한다.
DDL-auto
Data Definition Language에는 여러 설정이 있는데 주로 초기 개발단계에서 사용한다.
@Id
기본 키를 직접 할당하려면 @Id로 매피하면 된다.
@Id 적용 가능 자바 타입은 다음과 같다.
자바 기본형
자바 래퍼형
String
java.util.Date
java.sql.Date
java.math.BigDecimal
java.math.BigInteger
@GenerationType
데이터베이스의 종류도 많고 기본 키를 만드는 방법도 다양한다. GenerationType.AUTO를 선택한 데이터베이스는 방언에 따라 IDENTITY, SEQUENCE, TABEl 전략 중 하나를 자동으로 선택하는데 ORACLE은 SEQUNCE를 MySQL은 IDENTITY를 사용한다.
대리키 전략
Id 어노테이션을 단독으로 사용하면 기본 키를 애플리케이션에서 직접 할당해줘야 한다. 대신 데이터베이스가 생성해주는 값을 사용하려면
IDENTITY
기본 키 생성을 데이터베이스에 위임하는 전략으로 MySQL, PostgreSQL, SQL Server, DB2에서 사용한다
Identity 전략은 데이터베이스에 INSERT를 날린 후에 기본 키 값을 조회할 수 있는데 Statement.getGeneratedKey()를 사용하면 저장과 동시에 한번의 통신으로 키 값도 가져올 수 있다.
엔티티가 영속 상태가 되려면 식별자가 필요하기 때문에 INSERT 쿼리시 쓰기 지연은 동작하지 않는다
SEQUENCE
데이터베이스 시퀀스라는 기본 키를 할당하는 특별한 데이터 오브젝트를 사용하는 전략으로 ORACLE, PostgresSQL, DB2, H2데이터베이스에서 사용할 수 있다
SEQUENCE 사용 코드는 IDENTITY 전략과 같지만 내부 동작 방식에는 차이가 있다. SEQUENCE는 em.persist() 타이밍에 시퀀스를 사용해 식별자를 조회한다.
TABLE
키 생성 테이블을 이용, 키 생성 전용 테이블을 하나 만들고 여기에 이름과 값으로 사용할 컬럼을 만들어 데이터베이스 시퀀스를 흉내내는 전략이다. 모든 DB에 사용 가능하다 등의 대리키 전략이 있다
테이블 전략을 위해서는 키 생성 용도로 사용할 테이블을 만들어야 한다.
sequence_name 컬럼을 시퀀스 이름으로 사용하고 next_val 컬럼을 시퀀스 값으로 사용한다
TABLE 전략은 시퀀스 대신에 테이블을 사용한다는 것만 제외하면 SEQUENCE 전략과 내부 동작방식이 같다.
@Embeddable
@Embedded
Last updated