값 타입

강한친구·2022년 7월 13일
0

JPA

목록 보기
11/27

JPA의 데이터 타입 분류

엔티티 타입

  • @Entity로 정의하는 객체
  • 데이터가 변해도 식별자로 지속해서 추적

값타입

  • int, integer, String처럼 단순히 값으로 쓰는 자바기존타입
  • 식별자가 없어서 추적 불가능

값타입 분류

자바 기본 타입(int double)

생명주기를 엔티티에 의존한다. 엔티티 삭제하면 필드가 같이 사라지는 원리이다.
기본 타입은 절대로 공유해서는 안된다. 애초에 자바내부에서 값을 복사해서 만들지 절대로 공유하지 않는다.

  • 래퍼 클래스 (Integer, Long)
  • String
  • 임베디드 타입(Class 로 만들어서 쓰는 복합 값 타입)
  • 컬렉션 값 타입(임베디드나 래퍼 클래스를 여러개 한번에 담는 타입)

임베디드 타입

새로운 값 타입을 직접 정의할 수 있다. 기본값 타입들이 모여서 새로운 타입이 만들어지는것이기에, 복합 값 타입이라고도 부른다.

String 이름, int age라는 기본값을 가진 Member라는 객체를 만들면 member가 임베디드 타입이 되는것이다.

장점

  • 재사용성이 높고 높은 응집도를 보인다.

  • 해당 값 타입만 사용하는 의미있는 메서드를 사용할 수 있다.

  • 객체와 테이블을 아주 세밀하게 매핑하는것이 가능하다.

  • 임베디드 타입을 포함한 모든 값은, 값 타입을 소유한 엔티티 생명주기에 의존한다.

사용법

@Embeddable : 값 타입을 정의하는 곳에 표시
@Embedded : 값 타입을 사용하는 곳에 표시
기본생성자 필수

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

  • 임베디드 타입은 엔티티의 값일 뿐이다.
  • 임베디드 타입을 사용하기 전과 후에 매핑하는 테이블은 완전히 동일하다.
  • 객체 테이블을 아주 세밀하게 매핑할 수 있고, 잘 설계된 ORM 어플리케이션은 테이블수보다 클래스가 더 많다.

임베디드 타입과 연관관계

Entity의 Value가 되는 임베디드 타입은 또 다른 엔티티를 가지고 있을 수 있다.

한 엔티티에서 같은 값 타입을 사용하면 컬럼명이 중복된다.
@AttributeOverrides, @AttributeOverride를 사용해서 컬럼 명 속성을 재정의 할 수 있다.

값 타입과 불변 객체

값 타입은 객체를 단순화하기 위해 나온 개념이다.

임베디드 타입같은 값 타입을 여러 엔티티에서 공유하면 하나의 값만 바꿔도 값을 공유하는 모든 value가 바뀌는 side effect가 발생한다.

값타입은 따라서 실제 인스턴스를 공유하기보단, 복사를 해서 사용하는것이 안전한다.

객체타입의 한계

항상 값을 복사하면 공유참조로 발생하는 부작용은 막을 수 있다. 하지만 임베디드 처럼 직접 정으한 값 타입은 기본타입이 아니라 객체타입이다.

객체타입은 참조값을 대입하는데, 이 참조값 직접 대입을 막을 수가 없고, 객체의 공유 참조를 피할 수가 없다.

정리

기본타입

int a = 10; 
int b = a;//기본 타입은 값을 복사
b = 4;

객체타입

Address a = new Address(Old); 
Address b = a; //객체 타입은 참조를 전달
b. setCity(New)
// 이러면 a, b는 같은 인스턴스를 가르키고 있어서 a의 값도 new가 되어버린다.

따라서 이를 막기 위해서 불변객체를 만들어야한다. 불변객체는 만드는 방법이 몇개 있는데 대표적으로 생성자로만 값을 설정하고 수정자(Setter)를 만들지 않으면 된다.

만약 값을 진짜로 수정하고 싶으면, 생성자를 통해서 새로운 객체를 만들고, 값을 통으로 바꿔서 끼워야한다.

값 타입의 비교

값 타입은 인스턴스가 달라도 그 안의 값이 같으면 같은 것으로 본다.
객체타입의 경우 값이 같더라도, 참조 주소가 다르기때문에 다른값이 된다.

동일성 identity 비교와 동등성 equivalence 비교

==은 값의 비교이고, equals는 서로 다른 참조간의 값을 비교해주는 기능이다.

직접 정의한 값 타입은 (임베디드)는 equal로 동등성 비교를 해야한다.

값 타입 컬렉션

값 타입을 한개 이상 저장할 때 사용한다.
기본 자바 컬렉션 하위 메소드는 전부 사용 가능하다. 따라서 Set, List 역시 지원한다.

@ElementCollection, @CollectionTable

을 사용한다.

같은 테이블에 컬렉션을 저장훌 수는 없다. 따라서 별도의 테이블을 만들고 join해야한다.

값 타입 컬렉션 역시 값 타입이기에, 멤버의 생명주기에 의존하고 멤버값이 변하면 같이 변하게 된다.

컬렉션 제약사항

값 타입은 엔티티와 다르게 식별자 개념이 없다. 따라서 값 변경시 추적이 쉽지 않다.

값 타입 컬렉션에 변경사항이 발생하면, 주인 엔티티와 연관있는 모든 컬렉션 데이터를 삭제하고, 다시 저장한다.

값 타입 컬렉션을 매핑하는 테이블은 든 컬럼을 묶어서 기본
키를 구성해야 한다: null 입력X, 중복 저장X

결론

엔티티 타입의 특징

• 식별자O
• 생명 주기 관리
• 공유

값 타입의 특징

• 식별자X
• 생명 주기를 엔티티에 의존
• 공유하지 않는 것이 안전(복사해서 사용)
• 불변 객체로 만드는 것이 안전

값 타입은 정말 값 타입이라 판단될 때만 사용해야하고, 엔티티와 혼동해서 엔티티를 값 타입화하면 안된다.
식별자가 필요하고 지속해서 값을 추적, 변경해야한다면 그것은 엔티티로 만들어야한다.

0개의 댓글