JPA

[JPA] 데이터 타입

감자b 2024. 12. 29. 02:48

JPA의 데이터 타입은 크게 두 종류로 볼 수 있다.

엔티티 타입

  • @Entity로 정의하는 객체
  • 데이터가 변해도 식별자로 지속해서 추적 가능
  • 생명주기를 가지고 있으며, 공유 가능
  • 회원 엔티티의 키나 나이 값을 변경해도 식별자로 인식 가능

값 타입

  • int, Integer, String 같이 단순히 값으로 사용하는 자바 기본 타입이나 객체
  • 식별자가 없고 값만 있으므로 변경 시 추적 불가
  • 공유하지 않는 것이 안전, 불변으로 만들어야 함

값 타입의 종류

  • 기본 값 타입
    • 자바 기본 타입(int, double …)
    • 래퍼 클래스(Integer, Long …)
    • String
    기본 값 타입은 생명 주기를 엔티티에 의존한다. (엔티티가 삭제되면 엔티티의 name, age 필드도 삭제)
  • 임베디드 타입(복합 값 타입)
    • 새로운 값 타입을 직접 정의 (주로 기본 값 타입을 모아서 만들기 때문에 복합 값 타입(임베디드 타입) 이라고 한다.
    • (근무 기간 → 근무 시작일, 종료일 | 집 주소 → 도시명, 번지, 우편번호 …)
    • 엔티티도 들어올 수 있음(정확히는 엔티티의 참조인 엔티티의 ID가 들어올 수 있음)
    • 임베디드 타입은 기본생성자가 필수이며 해당 타입을 사용하는 곳에서는 @Embedded, 정의하는 클래스에는 @Embeddable 애노테이션을 사용한다.
    • 한 엔티티에서 같은 복합 값 타입을 사용하는 경우 컬럼명이 중복되므로 @AttributeOverrides, @AttributeOverride 를 사용해서 컬럼의 속성 명을 재정의 해야한다.
  • 컬렉션 값 타입
    • 값 타입을 하나 이상 저장할 때 사용한다.
    • @ElementCollection, @CollectionTable 애노테이션을 사용
    • 데이터베이스는 컬렉션을 같은 테이블에 저장할 수 없기에 컬렉션을 저장하기 위한 별도의 테이블이 필요
@ElementCollection
@CollectionTable(name = "FAVORITE_FOOD", joinColumns = 
		@JoinColumn(name = "MEMBER_ID")
)
@Column(name = "FOOD_NAME") // 값이 하나인 경우에는 예외적으로 컬럼 매핑이 가능
private Set<String> favoriteFoods = new HashSet<>();

@ElementCollection
@CollectionTable(name = "ADDRESS", joinColumns = 
		@JoinColumn(name = "MEMBER_ID")
)
private List<Address> addressHistory = new ArrayList<>();

값 타입 컬렉션 역시 별도의 테이블임에도 불구하고 스스로의 라이프 사이클을 가지지 않고 엔티티의 생명 주기에 의존한다.

즉 컬렉션 값을 변경해도 쿼리가 나간다. → 영속성 전이, 고아 객체 제거 기능을 지니고 있음

또한 조회 시 지연 로딩이 기본 전략이다. 하지만 값 타입은 앞서 말했다시피 식별자 개념이 없어 변경 시 추적이 어렵다.

그래서 값 타입 컬렉션을 매핑하는 테이블은 모든 컬럼을 묶어서 기본키를 구성한다. → 필드에 null 입력 불가, 중복 저장 불가

변경사항이 발생하면 주인 엔티티와 관련된 모든 데이터를 삭제, 값 타입 컬렉션에 있는 현재 값을 다시 저장한다. (list에 1,2,3이 있고 2를 지운다고 하면 1,2,3을 모두 삭제하는 쿼리 + 1,3 저장하는 쿼리 발생)

따라서 값 타입 컬렉션 대신에 일대다 관계를 위한 엔티티를 생성하고 영속성 전이, 고아 객체 제거를 사용해서 값 타입 컬렉션 처럼 사용하는 것을 권장한다.

 


값 타입과 불변 객체

직접 정의한 값 타입은 자바의 기본 타입이 아니라 객체 타입(값을 복사해서 사용하는 것이 아니라 참조를 대입함)

임베디드 타입 같은 값 타입을 여러 엔티티에서 공유하면 사이드 이펙트가 발생할 가능성이 높음

따라서 값 타입은 불변으로 설계해야 한다. (생성 시점 이후 값 변경 못하게 막아야 함)

 

값 타입 비교

값 타입은 동등성 비교를 해야함 (참조가 아닌 내부 값을 비교)


참고

 

자바 ORM 표준 JPA 프로그래밍 - 기본편 강의 | 김영한 - 인프런

김영한 | JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다., 실무에서도

www.inflearn.com