[JPA] 값 타입

2025. 7. 1. 15:45·DB Access/JPA

 

값 타입

#JPA/기본


/기본값 타입

JPA의 데이터 타입 분류

  • 엔티티 타입
    • @Entity로 정의하는 객체
    • 식별자로 추적 가능
    • 회원 값이 바껴도 PK로 추적 가능
  • 값 타입: 식별자 X 추적 불가
    • 회원의 주소 추적 불가. 단순히 값 처럼 취급됨

/값 타입 분류

/기본값 타입(int, double, Integer, Long, String, …)

  • 엔티티에 생명주기 의존(회원 삭제시 이름, 나이,… 삭제)
  • 공유하면 안됨. (동명이인 회원 A,B: 회원 A 이름 바꿨는데 회원 B 이름도 바뀌면 안됨)
  • ex) 래퍼 클래스, primitive type

/임베디드 타입(복합 값 타입)

  • 새로운 값 타입을 직접 정의할 수 있음.
    • ex) x, y 좌표를 담는 Position 클래스
    • ex) {근무 시작일, 근무 종료일}, {주소 도시, 주소 번지, 주소 우편번호}를 묶어서 임베디드 타입으로 사용

/임베디드 타입 사용법

  • @Embeddable: 값 타입을 정의하는 곳에 표시
  • @Embedded: 값 타입을 사용하는 곳에 표시
  • 둘 중 하나만 쓰고 하나는 생략 가능. 기본 생성자 필수

/임베디드 타입 장점

  • 재사용, 높은 응집도
  • 값 타입만 사용하는 의미있는 메서드를 만들 수 있음. validation rule
  • 임베디드 타입을 포함한 모든 값 타입은, 값 타입을 소유한 엔티티에 생명주기를 의존함

/임베디드 타입과 테이블 매핑

  • 임베디드 타입은 엔티티 값임 임베디드 타입을 사용하기 전과 후에 매핑하는 테이블은 같다.
    • 임베디드 타입에 대한 테이블이 따로 생기는 게 아님!
  • /임베디드 타입과 연관관계: 값 타입이 엔티티를 가지고 있을 수 있다.
  • /@AttributeOverride: 속성 재정의
    • 한 엔티티에서 값 타입을 중복해서 사용하려고 함(ex. 주소 집 주소, 직장 주소)
    • 칼럼이 중복됨 @AttributeOverrides, @AttributeOverride를 사용해서 컬럼 명 속성을 재정의
  • /임베디드 타입과 null : 임베디드 타입 값이 null이면 매핑 칼럼 모두 null

/값 타입과 불변 객체: 값 타입은 단순하고 안전하게 다뤄야 함.

  • 값 타입을 여러 엔티티에서 공유하면 위험함. 사이드 이펙트 발생 가능.
  • /값 타입 복사: 공유 대신 복사해서 사용

/객체 타입의 한계

  • 항상 복사해서 사용하면 좋지만, 임베디드 타입은 자바의 객체 타입이라, 객체 타입은 참조 값을 직접 대입하는 것을 막을 방법이 없다. 공유 참조를 피할 수 없음.

/불변 객체: 생성 시점 이후 절대 값을 변경할 수 없는 객체

  • 값 타입의 공유 참조는 피할 수 없지만, 객체 타입을 수정할 수 없게 만들어 부작용을 원천 차단할 수 있다.
  • 값 타입은 불변 객체(immutable object)로 설계해야함. setter 없이.
  • 이러면 값 타입을 변경하기 위해서는 새로운 값 타입 객체를 만들어야 한다.

/값 타입의 비교

  • 값 타입은 동등성 비교를 해야 함. 값이 같으면 같은 것! equals() 메소드를 적절하게 재정의(주로 모든 필드 사용)
    • 만약에 프록시를 고려한다면 address.street 이렇게 접근하는게 아니라, getter를 통해 접근해야 한다.

/값 타입 컬렉션: 실무에서는 값 타입 컬렉션 대신 일대다 관계를 고려하자.

  • 값 타입을 컬렉션에 담아서 쓰는 것 (ex. List<Address> )
    • 관계형 DB는 기본적으로 테이블 안에 컬렉션을 담을 수 있는 구조가 없다.
    • 결국에는 별도의 테이블로 1:다 로 풀어내야 한다.
  • 값 타입을 하나 이상 저장할 때 사용 (컬렉션이니까)
  • @ElementCollection, @CollectionTable 사용
  • 값 타입 컬렉션도 본인 스스로 라이프 사이클이 없다 영속정 전이 + 고아 객체 제거 기능을 필수로 가짐.
  • 값 타입 컬렉션도 지연 로딩 전략 사용한다(디폴트)
    • @ElementCollection의 fetch 속성의 기본값이 LAZY이다. 당연히 LAZY로 써야 한다.
  • 값 타입 컬렉션의 값만 변경해도 변경감지가 이뤄진다.

/값 타입 컬렉션의 제약사항

  • 식별자 없음 추적 어려움
  • 변경 사항 발생 시 전부 지우고 다시 저장한다. 쓰면 안 된다.
  • 모든 칼럼이 묶여서 PK를 이룸 null 입력 불가, 중복 저장 불가

/값 타입 컬렉션 대안

  • 실무에서는 상황에 따라 값 타입 컬렉션 대신에 일대다 관계를 고려
    • 일대다 관계를 위한 엔티티를 만들고, 그 내부에 값 타입을 쓰자(엔티티로 래핑하는 느낌)
      • ex) AddressEntity 내부에 Address
    • 그리고 영속성 전이(Cascade) + 고아 객체 제거를 사용해서 값 타입 컬렉션 처럼 사용
    • 이 경우 컬렉션 수정 후 persist시 일대다 단방향이기 때문에, 외래 키가 반대편에 있어 update 쿼리가 두 번 나감

/그러면 값 타입 컬렉션은 언제 사용할까?

  • 단순하고 추적할 필요도 없고 값을 바꿔도 업데이트 칠 이유가 없을 때 사용한다.

/정리

  • 엔티티와 값 타입을 혼동해서 엔티티를 값 타입으로 만들면 안됨. 확실히 값 타입이라고 판단될 때만 값 타입 사용
  • UML에서 값 타입은 스테레오 타입으로, <<Value Type>> 이렇게 적어주고 따로 빼주면 된다.

 

Ref) 김영한 자바 ORM 표준 JPA 프로그래밍 - 기본편

'DB Access > JPA' 카테고리의 다른 글

[JPA] JPQL(객체지향 쿼리 언어) 정리  (0) 2025.07.01
[JPA] 프록시와 연관관계 관리  (0) 2025.07.01
[JPA] 고급 매핑 - 상속 관계 매핑  (0) 2025.07.01
[JPA] 다양한 연관관계 매핑  (0) 2025.07.01
[JPA] 연관관계 매핑 기초  (0) 2025.07.01
'DB Access/JPA' 카테고리의 다른 글
  • [JPA] JPQL(객체지향 쿼리 언어) 정리
  • [JPA] 프록시와 연관관계 관리
  • [JPA] 고급 매핑 - 상속 관계 매핑
  • [JPA] 다양한 연관관계 매핑
lumana
lumana
배움을 나누는 공간 https://github.com/bebeis
  • lumana
    Brute force Study
    lumana
  • 전체
    오늘
    어제
    • 분류 전체보기 (462)
      • 개발 일지 (0)
        • Performance (0)
        • TroubleShooting (0)
        • Refactoring (0)
        • Code Style, Convetion (0)
        • Architecture (0)
      • Software Engineering (36)
        • Test (8)
        • 이론 (18)
        • Clean Code (10)
      • Java (72)
        • Basic (5)
        • Core (21)
        • Collection (7)
        • 멀티스레드&동시성 (13)
        • IO, Network (8)
        • Reflection, Annotation (3)
        • Modern Java(8~) (13)
        • JVM (2)
      • Spring (53)
        • Framework (12)
        • MVC (23)
        • Transaction (3)
        • AOP (11)
        • Boot (0)
        • AI (0)
      • DB Access (16)
        • Jdbc (1)
        • JdbcTemplate (0)
        • JPA (14)
        • Spring Data JPA (0)
        • QueryDSL (0)
      • Computer Science (130)
        • Data Structure (27)
        • OS (14)
        • Database (10)
        • Network (21)
        • 컴퓨터구조 (6)
        • 시스템 프로그래밍 (23)
        • Algorithm (29)
      • HTTP (8)
      • Infra (1)
        • Docker (1)
      • 프로그래밍언어론 (15)
      • Programming Language(Sub) (76)
        • Kotlin (0)
        • Python (25)
        • C++ (51)
        • JavaScript (0)
      • FE (11)
        • HTML (1)
        • CSS (9)
        • React (0)
        • Application (1)
      • Unix_Linux (0)
        • Common (0)
      • PS (13)
        • BOJ (7)
        • Tip (3)
        • 프로그래머스 (0)
        • CodeForce (0)
      • Book Review (4)
      • Math (3)
        • Linear Algebra (3)
      • AI (7)
        • DL (0)
        • ML (0)
        • DA (0)
        • Concepts (7)
      • 프리코스 (4)
      • Project Review (6)
      • LegacyPosts (11)
      • 모니터 (0)
      • Diary (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
lumana
[JPA] 값 타입
상단으로

티스토리툴바