[JPA] 데이터 타입
JPA의 데이터 타입은 크게 두 종류로 볼 수 있다.
엔티티 타입
- @Entity로 정의하는 객체
- 데이터가 변해도 식별자로 지속해서 추적 가능
- 생명주기를 가지고 있으며, 공유 가능
- 회원 엔티티의 키나 나이 값을 변경해도 식별자로 인식 가능
값 타입
- int, Integer, String 같이 단순히 값으로 사용하는 자바 기본 타입이나 객체
- 식별자가 없고 값만 있으므로 변경 시 추적 불가
- 공유하지 않는 것이 안전, 불변으로 만들어야 함
값 타입의 종류
- 기본 값 타입
- 자바 기본 타입(int, double …)
- 래퍼 클래스(Integer, Long …)
- String
- 임베디드 타입(복합 값 타입)
- 새로운 값 타입을 직접 정의 (주로 기본 값 타입을 모아서 만들기 때문에 복합 값 타입(임베디드 타입) 이라고 한다.
- (근무 기간 → 근무 시작일, 종료일 | 집 주소 → 도시명, 번지, 우편번호 …)
- 엔티티도 들어올 수 있음(정확히는 엔티티의 참조인 엔티티의 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