JPA의 데이터 타입 분류
엔티티 타입
- @Entity로 정의하는 객체
- 데이터가 변해도 식별자로 지속해서 추적 가능하다.
(Ex. 회원 엔티티의 키나 나이 값을 변경해도 식별자로 인식 가능)
값 타입
- int, Integer, String과 같이 단순히 값으로 사용하는 자바 기본 타입이나 객체를 말한다.
- 식별자가 없고 값만 있으므로 변경시 추적이 불가능하다.
(Ex. 숫자 100을 200으로 변경하면 완전히 다른 값이 된다.)
값 타입 분류
- 기본값 타입
- 자바 기본 타입(int, double)
- 래퍼 클래스(Integer, Long)
- String
- 임베디드 타입(Embedded Type, 복합 값 타입)
- 컬렉션 값 타입(Collection Value Type)
기본값 타입
- Ex. String name, int age 등
- 생명주기를 엔티티에 의존한다.
(Ex. 회원을 삭제하면 이름, 나이 등 필드들도 함께 삭제된다.)
- 값 타입을 공유하면 안 된다!
(Ex. 회원 이름 변경 시 다른 회원의 이름도 함께 변경되면 안된다.)
참고. 자바의 기본 타입은 절대 공유되지 않는다.
int, double과 같은 기본 타입(primitive type)은 항상 값을 복사하기 때문에 절대 공유되지 않는다.
하지만 Integer 같은 래퍼 클래스나 String 같은 특수한 클래스는 공유 가능한 객체이지만 변경되지 않는다.
임베디드 타입 (복합 값 타입)
임베디드 타입
- 새로운 값 타입을 직접 정의할 수 잇다.
- JPA는 임베디드 타입(embedded type)이라 한다.
- 주로 기본 값 타입을 모아서 만들어서 복합 값 타입이라고도 한다.
- int, String과 같은 값 타입이기 때문에 변경하면 추적할 수 없다.
임베디드 타입 예시
- 회원 엔티티는 이름, 근무 시작일, 근무 종료일, 주소 도시, 주소 번지, 주소 우편 번호를 가진다.
- 회원 엔티티의 근무 시작일, 근무 종료일은 근무 기간으로, 주소들은 집 주소로 묶을 수 있을 것이다.
- 따라서 Period와 Address라는 클래스를 만들어 연결해주면 재사용성과 편의가 향상될 것이다.
- 사용법
- @Embeddable : 값 타입을 정의 하는 곳에 표시
(값 타입 정의 시 기본 생성자는 필수이다.)
- @Embedded : 값 타입을 사용하는 곳에 표시
@Entity
public class Member {
...
@Embedded
private Period workPeriod;
}
~~~~~~~~~~~~~~~~~~~~~~~~
@Embeddable
public class Period {
private Date startDate;
private Date endDate;
public Period(...) { ... }
public boolean isWork() { ... }
}
임베디드 타입의 장점
- 재사용성
- 높은 응집도
- Period.isWork()과 같이 해당 값 타입만 사용하는 의미 있는 메소드를 만들 수 있다. 이를 통해 더욱 객체 지향적으로 프로그래밍이 가능하다.
- 임베디드 타입을 포함한 모든 값 타입은 값 타입을 소유한 엔티티의 생명주기에 의존한다.
임베디드 타입과 테이블 매핑
- 임베디드 타입은 엔티티의 값일 뿐이다.
- 임베디드 타입을 사용하기 전과 후에 매핑하는 테이블은 같다.
- 객체와 테이블을 아주 세밀하게(find-grained) 매핑하는 것이 가능하다.
- 잘 설계한 ORM 어플리케이션은 매핑한 테이블의 수보다 클래스의 수가 더 많다.
@AttributeOverride : 속성 재정의
- 한 엔티티 내에서 같은 값 타입을 사용하면 Column 명이 중복될 것이다. 이때 @AttributeOverride를 통해 Column 명 속성을 재정의하여 해결할 수 있다.
[Reference]
Inflearn 김영한 님의 자바 ORM 표준 JPA 프로그래밍 - 기본편 : https://www.inflearn.com/course/ORM-JPA-Basic/dashboard