[JPA] 값 타입 :: 잡다한 프로그래밍
반응형

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

+ Recent posts