자바 ORM 표준 JPA 프로그래밍 - 값 타입

jaeeunxo1·2021년 1월 13일
0

springboot

목록 보기
13/17
post-thumbnail

1. 기본 값 타입

가장 단순한 기본값 타입이다. 엔티티는 식별자 값도 가지고 생명주기도 있지만 값 타입인 name, age 속성은 식별자 값도 없고 생명주기도 회원 엔티티에 의존한다. 값 타입은 공유하면 안된다. (다른 회원의 정보를 변경할 때, 나의 정보까지 변경되는 것은 말도 안된다.)

2. 임베디드 타입

새로운 값 타입을 직접 정의해서 사용할 수 있는데, JPA에서는 이것을 임베디드 타입이라 한다.
임베디드 타입은 기본 생성자가 필수이다. 임베디드 타입은 값이 속한 엔티티의 테이블에 매핑한다.

@Embedded : 값 타입을 정의하는 곳에 표시
@Embeddable : 값 타입을 사용하는 곳에 표시

2-1 임베디드 속성 재정의

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

2-2 임베디드 타입과 null

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

3. 값 타입과 불변 객체

3-1 값 타입 공유 참조

항상 값을 복사해서 사용하면 공유 참조로 인해 발생하는 부작용을 피할 수 있다.
임베디드 타입처럼 직접 정의한 값 타입은 자바의 기본 타입이 아니라 객체 타입이다.
객체 타입은 참조 값을 직접 대입하는 것을 막을 방법이 없다.

3-2 불변 객체 ✨

객체 타입을 수정할 수 없게 만든다. 값 타입은 immutable object 로 설계해야 한다.
✨ setter를 private 또는 아예 사용하지 않는다.

영한님 : 불변이라는 작은 제약으로 부작용이라는 큰 재앙을 막을 수 있다.

3-3 값 타입의 비교

객체는 다른 인스턴스이므로 결과는 항상 거짓이다. 값 타입은 비록 인스턴스가 달라도 그 안에 값이 같으면 같은 것으로 봐야 한다.
따라서 equals() 메서드를 재정의할 때는 보통 모든 필드의 값을 비교하도록 구현한다.

4. 값 타입의 컬렉션

값 타입을 하나 이상 저장할 때 사용
데이터베이스는 컬렉션을 같은 테이블에 저장할 수 없다. 컬렉션을 저장하기 위한 별도의 테이블이 필요하다.

@ElementCollection : 값타입 컬렉션이라고 지정해준다.
@CollectionTable : 원하는 컬럼을 지정해줄 수 있다.

값 타입의 컬렉션은 다른 테이블이지만 엔티티를 저장할 때 같이 저장된다. 즉 값 타입은 생명주기가 엔티티에 의존한다는 것이다. (고아객체의 특성을 기본적으로 갖고, 지연로딩이다.)

4-1 값 타입 컬렉션의 제약사항

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

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

  3. 값 타입은 엔티티와 다르게 식별자 개념이 없기 때문에, 변경되면 추적이 어렵다.

4-2 값 타입 컬렉션 대안

영한님 : 실무에서는 상황에 따라 값 타입 컬렉션 대신에 일대다 관계를 고려해야 한다. 또는 영속성 전이(Cscade) + 고아 객체 제거를 사용한다. 정말 단순히 셀렉트박스에서 메뉴를 선택할 경우에만 사용!

profile
Backend 🖤

0개의 댓글