@Entity로 정의하는 객체int, Integer, String처럼 단순히 값으로 사용하는 자바 기본 타입이나 객체int, double)Integer, Long)String: String name, ing age...
생명주기를 엔티티에 의존한다는 중요한 특징이 있다.
(예를 들어 회원을 삭제하면 이름, 나이 필드도 함께 삭제된다.)
값 타입은 공유하면 안된다.
(예를 들어 회원 이름 변경시 다른 회원의 이름도 변경 되어버리면 안되기 때문이다.)
int, double 같이 기본 타입(primitive type)은 절대 공유하면 안된다.
기본 타입은 항상 값을 복사한다.
Integer와 같이 래퍼 클래스나 String같은 특수한 클래스는 공유가 가능한 객체이지만 변경 불가능
: 복합 값 타입, 내장 타입이라고도 함
int, String과 같은 값 타입(추적도 변경도 안됨)요구사항
- 회원 엔티티는 이름, 근무 시작일, 근무 종료일, 주소 도시, 주소 번지, 주소 우편번호를 가짐
- 회원 엔티티는 이름, 근무 기간, 집 주소를 가짐
@Embeddable: 값 타입을 정의하는 곳에 표시@Embedded: 값 타입을 사용하는 곳에 표시


@AttributeOverride: 속성 재정의
한 엔티티에서 같은 값 타입을 사용하면 컬럼명이 중복 되어버린다.
그럴 때 @AttributeOverrides와 @AttributeOverride를 사용해 컬러 명 속성을 재정의 한다.
📌 임베디드 타입의 값이 null이면 매핑한 컬럼 값은 모두 null이다.

값 타입은 복잡한 객체 세상을 조금이라도 단순화하기 위해 만든 개념. 따라서 값 타입은 단순하고 안전하게 다룰 수 있어야 함




int a = 10;
int b = a; // 기본 타입은 값을 복사하기 때문에 b = 10인 상태
b = 4;
// b만 4로 변경
Address a = new Address("old");
Address b = a; // 객체 타입은 참조를 전달
b.setCity("new");
// a와 b 가 같은 인스턴스를 가지고 있으므로 둘 다 "new"로 바뀜
📌
Integer,String은 자바가 제공하는 대표적인 불변 객체
값 타입은 인스턴스가 달라도 그 안의 값이 같으면 같은 것으로 봐야한다.
int a = 10; int b = 10;
이라면 a==b 는 true이다.
Address a = new Address("ㅇㅇ시");
Address b = new Address("ㅇㅇ시");
라면 a==b 는 false이다.
==사용equals() 사용: 값 타입을 컬렉션에 담아 쓰는 것

@ElementCollection, CollectionTable사용해 매핑📌 값 타입 컬렉션은 영속성 전이(Cascade) + 고아 객체 제거 기능을 필수로 가진다고 볼 수 있다.
// JpaMain.java
try {
Member member = new Member();
member.setUsername("member1");
member.setHomeAddress(new Address("homeCity", "street", "100"));
member.getFavoriteFoods().add("물회");
member.getFavoriteFoods().add("미역국");
member.getFavoriteFoods().add("계란");
member.getAddressHistory().add(new Address("old1", "street", "100"));
member.getAddressHistory().add(new Address("old2", "street", "100"));
em.persist(member);
em.flush();
em.clear();
System.out.println("====== START ======");
Member findMember = em.find(Member.class, member.getId());
// homeCity -> newCity
Address a = findMember.getHomeAddress();
findMember.setHomeAddress(new Address("newCity", a.getStreet(), a.getZipcode()));
// 물회 -> 매운탕
findMember.getFavoriteFoods().remove("물회");
findMember.getFavoriteFoods().add("매운탕");
findMember.getAddressHistory().remove(new Address("old1", "street", "100"));
findMember.getAddressHistory().add(new Address("newCity1", "street", "100"));
tx.commit();

값 타입은 정말 값 타입이라고 판단될 때만 사용해야 한다.
엔티티와 값 타입을 혼동해 엔티티를 값 타입으로 만들면 안된다.
식별자가 필요하고, 지속해서 값을 추적, 변경해야 한다면 그것은 값 타입이 아닌 엔티티이다.
✔️ 실전 예제는 jpashop 프로젝트, jpashop DB를 사용합니다.
📌 참고
Address.java를 생성해 객체지향적으로 만들었다.
자세한 코드는 깃허브를 참고