반응형
JPA 값 타입(Value Type) 정리
JPA에서는 데이터를 다루는 방식에 따라 엔티티(Entity Type)와 값 타입(Value Type)으로 구분합니다.
1. 엔티티 타입 (Entity Type)
- @Entity로 정의되는 클래스
- 식별자(PK)를 통해 영속성 컨텍스트에서 추적 가능
- 변경이 발생해도 식별자 기준으로 동일 객체로 인식
- 생명주기를 독립적으로 가짐
예: Member 엔티티의 age가 바뀌어도 여전히 같은 식별자(PK)를 가진 동일한 객체로 추적 가능
2. 값 타입 (Value Type)
- int, Integer, String 처럼 단순히 값으로 사용하는 자바 기본타입이나 객체
- 엔티티처럼 독립적인 식별자 없음
- 단순히 값 자체로만 의미를 가짐 → 변경 시 완전히 다른 값으로 교체됨
- 생명주기는 소유한 엔티티에 의존
기본값 타입
- Java 기본 타입 혹은 래퍼 클래스 (int, Integer, String, Long 등)
- 예: String name, int age
- 엔티티와 함께 저장되고, 삭제됨 (생명주기를 엔티티에 의존함)
Java 기본 타입은 값 자체를 복사 → 공유 없음
int a = 10; int b = a; a = 20; // b는 여전히 10
주의: 래퍼 클래스나 String은 공유될 수 있으나, 불변성 때문에 값 변경이 불가함
3. 임베디드 타입 (Embedded Type)
- 여러 개의 기본 값 타입을 묶어서 하나의 값 타입으로 정의
- 복합 값 타입 또는 임베디드 타입이라고 부름
- @Embeddable + @Embedded 조합으로 사용
- @Embeddable: 값 타입을 정의하는 곳에 표시
- @Embedded: 값 타입을 사용하는 곳에표시
- 기본 생성자 필요
회원 엔티티는 이름, 근무 시작일, 근무 종료일, 주소 도시, 주소 번지, 우편번호를 가진다
좀더 객체 지향적으로 설계하면 회원 엔티티는 이름, 근무기간, 집주소를 가진다
[적용 예시]
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
private String username;
@Embedded
private Period workPeriod;
@Embedded
private Address homeAddress;
}
@Embeddable
public class Period {
private LocalDateTime startDate;
private LocalDateTime endDate;
public boolean isWork() {
return startDate != null && endDate == null;
}
}
@Embeddable
public class Address {
private String city;
private String street;
private String zipcode;
}
Period와 Address는 객체일 뿐, DB에서는 각각의 필드가 컬럼으로 매핑됨
장점
- 재사용 가능
- 응집력 높은 설계 (ex: Period.isWork() 같은 도메인 메서드 추가 가능)
- 엔티티 클래스의 가독성 개선
- 테이블 구조는 변하지 않음
임베디드 타입 + 연관관계
- 임베디드 타입 내부에 다른 엔티티를 가질 수 있음 (ex: PhoneNumber 내에 Phone 엔티티 FK)
- 단, 임베디드 타입 자체는 엔티티가 아님 → 식별자 없음
임베디드 값이 null일 때
- 해당 값 타입의 모든 필드가 null로 들어감
- ex: workAddress == null → WORK_CITY, WORK_STREET, WORK_ZIPCODE 모두 null
동일한 임베디드 객체를 2개이상 쓰고싶다면? 속성 재정의: @AttributeOverrides
같은 임베디드 타입을 두 번 이상 쓰려면 속성 이름이 충돌함 → 이때 @AttributeOverrides 사용
@Embedded
private Address homeAddress;
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "city", column = @Column(name = "WORK_CITY")),
@AttributeOverride(name = "street", column = @Column(name = "WORK_STREET")),
@AttributeOverride(name = "zipcode", column = @Column(name = "WORK_ZIPCODE"))
})
private Address workAddress;
반응형
'프로그래밍 > JPA' 카테고리의 다른 글
[JPA] 값 타입 컬렉션 (1) | 2025.07.25 |
---|---|
[JPA] 값 타입과 불변 객체 (2) | 2025.07.23 |
[JPA] 영속성 전이 CASCADE (2) | 2025.07.17 |
[JPA] 즉시 로딩과 지연 로딩 (2) | 2025.07.16 |
[JPA] 프록시와 연관관계 관리 (0) | 2025.07.15 |