#09 값 타입

김영한 저 "자바 ORM 표준 JPA 프로그래밍, 2015"을 읽고 정리한 내용입니다.

  • 데이터타입 크게 분류

    • 엔티티타입 @Entity

    • 값타입 (basic value, embedded, collection)

  • 값타입 3종류

    • 값타입 - String, int 등

    • 컬렉션 값 타입 - 하나 이상의 값

    • 임베디드 타입 - 사용자가 직접정의

9.1 기본값 타입

생략

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

@Embedded @Embeddable

//변경전
@Entity
public class Member {
    //...

    //근무기간
    @Temporal(TemporalType.DATE) Date startDate;
    @Temporal(TemporalType.DATE) Date endDate;
    
    //집 주소 표현
    private String city;
    private String street;
    private String zipcode;
    //...
}

//변경후
//재사용할 수 있고 객체지향적이고 응집력이 높다.
@Entity
public class Member {
    //...
    private String name;
    @Embedded Period workPeriod; //근무 기간
    @Embedded Address homeAddress; //집 주소
   //...
}
  • 임베디드 타입은 기본 생성자가 필수

  • 모든 값 타입은 엔티티의 생명주기에 의존하므로 엔티 티와 임베디드 타입의 관계를 UML로 표현하면 구현(composition) 관계

  • 잘 설계한 ORM 애플리케이션은 매핑한 테이블의 수보다 클래스의 수가 더 많다

9.2.1 @AttributeOverride 속성 재정의

회원에게 주소가 하나 더 필요하면 어떻게 해야 할까?

어노테이션을 너무 사용해 복잡해 보이지만, 한엔티티에 같은 임베디드 타입을 중복해서 사용한는 일은 많지 않다.

9.2.2 임베디드 타입과 NULL

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

9.3 값 타입과 불변 객체

값타입은 단순하고 안전하게 다룰 수 있어야 한다.

9.3.1 공유참조

임베디드 타입 같은 값 타입을 여러 엔티티에서 공유하면 위험하다.

  • 회원1의 주소도 NewCity로 변경

  • 부작용을 막으려면 값을 복사해서 사용하면 된다.

9.3.2 복사

clone()

9.3.3 불변객체

객체를 불변하게 만들면 값을 수정할 수 없으므로 부작용을 원천 차단할 수 있다.

setCity() 같은 수정자 메소드를 모두 제거한다.

9.4 값타입의 비교

  • Identity, Equivalence 비교

자바에서 equals() 재정의하면 hashCode()도 재정의하는 것이 안전하다. 컬렉션(HashSet, HashMap)이 정상 동작하게 만든다.

9.5 값타입 컬렉션

데이터베이스의 테이블은 컬럼 안에 컬렉션을 포함할 수 없다. 별도의 테이블을 추가하 고 @CollectionTable를 사용해서 추가한 테이블을 매핑해야 한다.

모든 컬럼을 묶어서 기본 키를 구성한다.

9.5.1 컬렉션 사용

값 타입 컬렉션은 영속성 전이(Cascade) + 고아 객체 제거(ORPHAN REMOVE) 기능을 필수로 가진다고 볼 수 있다.

9.5.2 제약사항

  • 값 타입 컬렉션에 변경 사항이 발생하면, 값 타입 컬렉션이 매핑된 테이블의 연관된 모든 데이터를 삭제하고 다시 저장한다.

  • 같은 값을 중복해서 저장할 수 없는 제약(모든값이 기본키로 구성)

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

  • @Emedded -> @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) 변경한다.

9.6 정리

엔티티 타입과 값 타입의 특징

엔티티 타입의 특징

  • 식별자가 있다.

    • 엔티티 타입은 식별자가 있고 식별자로 구별할 수 있다.

  • 생명 주기가 있다.

    • 생성하고, 영속화하고, 소멸하는 생명 주기가 있다.

    • em.persist(entity)로 영속화 한다.

    • em.remove(entity)로 제거한다.

  • 공유할 수 있다.

    • 참조 값을 공유할 수 있다. 이것을 공유 참조라 한다.

    • 예를 들어, 회원 엔티티가 있다면 다른 엔티티에서 얼마든지 회원 엔티티를 참조 할 수 있다.

값 타입의 특징

  • 식별자가 없다.

  • 생명 주를 엔티티에 의존한다.

    • 스스로 생명주기를 가지지 않고 엔티티에 의존한다. 의존하는 엔티티를 제거하면 같이 제거된다.

  • 공유하지 않는 것이 안전하다.

    • 엔티티 타입과는 다르게 공유하지 않는 것이 안전하다. 대신에 값을 복사해서 사용해야 한다.

    • 오직 하나의 주인만이 관리해야 한다.

    • 불변 객체로 만드는 것이 안전하다.

Last updated