값 타입

종류

  • 기본값 타입
  • 임베디드 타입
  • 컬렉션 타입


기본값 타입

절대 공유 X, 기본 타입은 항 값을 복사한다.
Integer타입 같은 래퍼 클래스나 String 타입은 특수한 클래스는 공유 가능하지만 변경이 안되도록 막아야 한다.(Side Effect 방지)

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

주로 기본 값 타입을 모아서 만듬 테이블은 하나인데, 속성들을 그룹화해서 클래스를 설계할 수 있다.

사용법

@Embedded   // 사용하는 곳에 사용
@Embeddable // 정의할 때 사용
/** 기본 생성자 필수 **/

장점 : 재사용, 높은 응집도, 해당 값타입만 사용하는 의미 있는 메서드를 만들어서 객체 지향에 맞는 설계 가능

임베디드 타입은 임베디드 타입과 엔티티 타입을 가질 수 있다. 하나의 엔티티에서 같은 타입을 중복해서 사용하려면?

@AttributeOverrides({
            @AttributeOveride(name="필드명",
                column=@Column("새 필드명")),
            @AttributeOveride(name="필드명",
                column=@Column("새 필드명")),
             ..
})

*임베디드 객체가 null이면 매핑한 컬럼 모두 null

값 타입과 불변 객체

값타입의 인스턴스를 공유하는 것은 위험. 한쪽에 수정하면 다른 엔티티 특성도 영향을 미칠 수 있다.

불변 객체로 부작용을 원천 차단하자..!

  • 객체 타입 수정할 수 없게 만들면 됨.
  • 갑 타입은 불변 객체로 설계해야함
    => 생성자만 만들고 Setter는 만들지 않는다.

값을 바꾸고 싶을 때는 새로 만들어서 대입하는게 좋다.

값 타입의 비교

  • 동일성 비교(==) : 인스턴스의 참조 값 비교
  • 동등성 비교(equals()) : 인스턴스의 값을 비교

equalts를 주로 모든 필드에 대해 적절하게 재정의 해야함(한다면 hashcode도 구현해줘야함)

값 타입 컬렉션

@ElementCollection
@CollectionTable

선언하는 엔티티와 같은 라이프 사이클을 가진다.

값 타입 컬렉션은 지연 로딩 전략을 사용

제약사항

  • 값이 변경되면 추적이 어렵다.
  • 변경 사항 발생 시 주인 엔티티와 연관된 모든 데이터를 삭제하고, 값 타입 컬렉션 있는 현재 값을 모두 다시 저장함. => 값 타입 컬렉션을 쓰지 말아야 할 결정적인 이유
  • 값 타입 컬렉션을 매핑하는 테이블은 모든 컬럼을 묶어서 기본키를 구성해야 한다.

(@OrderColumn 을 사용하는 방법도 있지만, 이것도 위험하다.)

* 실무에서는 상황에 따라 값 타입 컬렉션 대안으로 일대다 연관관계 사용을 고려하는 것이 좋다. (CascadeType.ALL, alphan = true 를 사용하는것이 왜 적합한지)

* 정말 단순한 경우 쓸 수 있다.

* 식별자가 필요하고, 지속해서 값을 추적, 변경해야 한다면 그것은 값 타입이 ㅏ닌 엔티티