값 타입

inho ha·2022년 5월 20일
0

자바 ORM 표준 JPA 프로그래밍

http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&ejkGb=KOR&barcode=9788960777330

값 타입

JPA의 테이터 타입은 엔티티 타입과 값 타입으로 나눌 수 있다.

엔티티 타입은 식별자를 통해 속성이 바뀌얻 같은 엔티티 임을 알 수 있지만

값 타입은 식별자가 없고 속성만 있으므로 속성이 바뀌면 구별 불가능하다.

값 타입은 기본값 타입, 임베디드 타입, 컬렉션 값 타입이 있다.

기본값 타입

Member 엔티티의 멤버 변수 String name, int age 등이 기본 값 타입이다.
name, age 속성은 식별자 값도 없다.
생명주기 또한 Member 엔티티에 의존한다.

값 타입은 공유하면 안된다.
한 member 의 name을 변경했을 때 다른 member 의 name이 변경되면 안되기 때문이다.

클래스가 아닌 값 타입은 대입 연산자로 복사를 해도 값만 복사된다.

임베디드 타입

새로운 값 타입을 직접 정의해서 사용하는 것을 JPA에서는 임베디드 타입이라고 한다.
예를들어 주소를 저장할때 String city, String street, String zipcode 이렇게 따로 관리하던 걸 이 세가지 속성을 가지는 Address 타입을 만들어 사용할 수 있다.

정의하려는 타입을 클래스로 구현하고 @Embeddable을 붙여주면 된다.
사용할 때는 타입 왼쪽에 @Embedded 을 붙여주면 된다.

임베디드 타입은 기본 생성자가 필수다.

임베디드 타입 또한 값 타입이므로 엔티티의 생명주기에 의존한다.
이 때문에 엔티티와 임베디드 타입의 관계를 UML로 표현하면 컴포지션 관계가 된다.

하이버네이트는 임베디드 타입을 컴포넌트라 한다.

임베디드 타입은 엔티티의 값일 뿐이므로 기존 속성을 임베디드 타입으로 바꾸어도 테이블은 변하지 않는다.

임베디드 타입과 연관관계

임베디드 타입의 속성이 연관관계를 가지는 경우 해당 속성에 어노테이션으로 연관관계를 설정해주면 된다.

임베디드 연관관계 재정의

임베디드 타입에 정의한 매핑정보를 재정의하려면 엔티티에서 임베디드 타입에 @AttributeOverride를 사용하면 된다.

임베디드 타입 null

임베디드 타입이 Null이면 매핑한 컬럼 값은 모두 null이 된다.

값 타입과 불변 객체

임베디드 타입처럼 직접 정의한 값 타입은 자바의 기본 타입이 아니라 객체 타입이다.
따라서 대입 연산사를 사용하면 같은 인스턴스를 가리키게 되기 때문에 문제가 발생할 수 있다.

따라서 clone 같은 메서드를 작성하여 속성의 값만 복사할 수 있도록 해주어야한다.

또한 임베디드 타입의 클래스에 setter 메서드를 제거하여 만약 공유 참조를 해도 값을 변경하지 못하게 하여 부작용의 발생을 막을 수 있다.

불변 객체

이처럼 객체를 불변하게 만들어 값을 수정할 수 없게 부작용을 차단한 것을 불변 객체라 한다.
값 타입은 가능하면 불변 객체로 설계해야 한다.

Integer, String 은 자바가 제공하는 불변 객체이다.

값 타입의 비교

임베디드 타입의 경우에는 객체이므로 equals 메서드를 재정의하여 동등성을 비교 할 수 있다.
equals를 재정의 할 때는 hashCode 메서드도 재정의 하는 것이 안전하다.
그래야 해시를 사용하는 컬렉션이 정상 작동할 수 있다.

자바 ID의 자동 재정의 기능을 이용하면 편하다.

값 타입 컬렉션

값 타입을 하나 이상 저장하려면 컬렉션에 보관하고 @ElementCollection 과 @CollectionTable 어노텡션을 사용하면 된다.

관계형 데이터베이스의 테이블은 컬럼안에 컬렉션을 포함할 수 없다.
@CollectionTable 어노테이션을 사용하면 테이블이 추가되고 매핑된다.

값 타입 컬렉션은 영속성 전이와 고아 객체 제거 기능을 필수도 가진다.

값 타입 컬렉션 조회시 페치 전략은 LAYZ 가 기본 값이다.

값 타입 컬렉션의 제약사항

특정 엔티티 하나에 소속된 값 타입은 값이 변경되어도 자신이 소속된 엔티티를 데이터베이스에서 찾고 값을 변경하면 된다.

값 타입 컬렉션은 별도의 테이블에 보관 되기 때문에 수정 되었을때 원본 데이터를 찾기 어려워 연관된 데이터를 모두 삭제하고 수정된 컬렉션 전체를 다시 저장한다.

따라서 값 타입 컬렉션이 매핑된 테이블에 데이터가 많다면 값 타입 컬렉션 대신 일대다 관계를 고려해야 한다.

또한 값 타입 컬렉션을 매핑하는 테이블은 모든 컬럼을 묶어서 기본 키를 구성해야한다.
따라서 컬럼에 null을 입력할 수 없고, 같은 값을 중복해서 저장할 수 없다.

이를 해결하기 위해서는 일대다 관계로 설정하면 된다.

profile
inho ha / ian(swatchon) / iha(42seoul)

0개의 댓글