기본값 타입
임베디드 타입 (embedded type, 복합 값 타입)
컬렉션 값 타입(collection value type)
ex) String name, int age
생명주기를 엔티티에 의존
ex. 회원 삭제시 이름, 나이 필드도 삭제
값 타입은 공유 X
ex. 회원 이름 변경시 다른 회원의 이름도 함께 변경되면 안 됨
🔎 자바의 기본 타입은 절대 공유되지 않음
기본 타입은 항상 값을 복사한다
래퍼 클래스 혹은 String 같은 특수한 클래스는 공유 가능한 객체이지만 변경 불가
ex) 회원 엔티티는 이름, 근무 시작일, 근무 종료일, 주소 도시, 주소 번지, 주소 우편번호를 가진다
👉 회원 엔티티는 이름, 근무 기간, 집 주소를 가진다
예시처럼 묶어낼 수 있는 게 임베디드 타입이다
기본 생성자 필수 (public, protected)
임베디드 타입의 값이 null 👉 매핑한 컬럼 값 모두 null
장점
값 타입을 정의하는 곳에 표시
값 타입을 사용하는 곳에 표시
💡 둘 중 하나만 있어도 되지만 둘 다 사용
임베디드 타입은 엔티티의 값일 뿐이다
임베디드 타입을 사용하기 전과 후에 매핑하는 테이블은 같다
but, 객체와 테이블을 아주 세밀하게(find-grained) 매핑하는 것이 가능
잘 설계한 ORM 애플리케이션은 매핑한 테이블의 수보다 클래스의 수가 더 많음
임베디드 타입은 Entity를 가질 수 있다
한 엔티티에서 같은 값 타입 사용시 컬럼 명 중복
@AttributeOverrides , @AttributeOverride를 사용하여 컬럼 명 속성 재정의
값 타입의 실제 인스턴스인 값을 공유하는 것은 위험
인스턴스를 복사하여 사용한다면?
공유 참조로 인해 발생하는 부작용은 피할 수 있으나
문제는 기본 타입이 아니라 객체 타입
객체 타입은 참조 값을 직접 대입하는 것(공유 참조)를 막을 방법이 없다
기본 타입(primitive type)
int a = 10;
int b = a; //기본 타입은 값을 복사
b = 4;
객체 타입
Address a = new Address("old");
Address b = a; //객체 타입은 참조를 전달
b.setCity("New");
때문에,
💡 JPA 스펙상 엔티티나 임베디드 타입은 기본 생성자를 public 또는 protected 로 설정해야 한다. (JPA 구현 라이브러리가 객체 생성시, 리플랙션 같은 기술을 사용할 수 있게 지원해야 하기 때문)
따라서 protected로 설정하는 것이 상대적으로 안전
값 타입은 인스턴스가 달라도 그 안에 값이 같으면 같은 것으로 봐야 한다
== 사용equals() 사용👉 값 타입은 a.equals(b)를 사용하여 동등성 비교를 해야 함
👉 값 타입의 equals() 메소드를 적절하게 재정의 (주로 모든 필드 재정의)
