9.1 기본값 타입
@Entity
public class Member{
@Id @GeneratedValue
private Long id;
private String name;
private int age;
}
기본값 타입
9.2 임베디드 타입(복합 값 타입)
임베디드 타입(embedded type)
- 새로운 값 타입을 직접 정의해서 사용하는 것
@Entity
public class Member{
@Id @GeneratedValue
private Lond id;
private String name;
@Embedded Period workPeriod; //근무 기간
@Embedded Address homeAddress; //집 주소
}
값 타입 적용 회원 엔티티
@Embeddable
public class Period{
@Temporal(TemporalType.DATE) java.util.Date startDate;
@Temporal(TemporalType.DATE) java.util.Date endDate;
//..
public boolean isWork(Date date){
// 값 타입을 위한 메서드를 정의할 수 있다
}
}
기간 임베디드 타입
@Embeddable
public class Address{
@Column(name="city") //매핑할 컬럼 정의 가능
private String city;
private String street;
private String zipcode;
//..
}
주소 임베디드 타입
- 새로 정의한 값 타입들은 재사용할 수 있고 응집도도 아주 높다
- @Embeddable: 값 타입을 정의하는 곳에 표시
- @Embedded: 값 타입을 사용하는 곳에 표시
- 임베디드 타입을 포함한 모든 값 타입은 엔티티의 생명주기에 의존하므로 엔티티와 임베디드 타입의 관계를 UML로 표현하면 컴포지션(composition) 관계가 된다
9.3 값 타입과 불변 객체
값 타입은 복잡한 객체 세상을 조금이라도 단순화하려고 만든 개념이다
9.3.1 값 타입 공유 참조
member1.setHomeAddress(new Address("OldCity"));
Address address = member1.getHomeAddress();
address.setCity("NewCity"); // 회원1의 address 값을 공유해서 사용
member2.setHomeAddress(address);
회원2의 주소만 "NewCity"로 변경되길 기대했지만 회원1의 주소도 "NewCity"로 변경되어 버린다 => 회원1과 회원2가 같은 address 인스턴스를 참조하기 때문이다
이렇듯 뭔가를 수정했는데 전혀 예상치 못한 곳에서 문제가 발생하는 것을 부작용(side effect)라고 한다 => 이런 부작용을 막으려면 값을 복사해서 사용하면 된다
9.3.2 값 타입 복사
항상 값을 복사해서 사용하면 공유 참조로 인해 발생하는 부작용을 피할 수 있다
문제!!!
- 임베디드 타입처럼 직접 정의한 값 타입은 자바의 기본 타입(primitive type)이 아니라 객체 타입이라는 것이다
- 객체를 대입할 때마다 인스턴스를 대입하면 공유 참조를 피할 수 있다
- 또 다른 문제!! => 복사하지 않고 원본의 참조 값을 직접 넘기는 것을 막을 방법이 없다는 것이다
- 객체의 공유 참조는 피할 수 없다
9.3.3 불변 객체
객체를 불변하게 만들면 값을 수정할 수 없으므로 부작용을 원천 차단할 수 있다. 따라서 값 타입은 될 수 있으면 불변 객체(immatable) 로 설계하자
9.4 값 타입의 비교
- 동일성(identity) 비교 : 인스턴스 참조 값을 비교, == 사용
- 동등성(equivalence) 비교 : 인스턴스 값을 비교, equals() 사용
9.6 정리
엔티티 타입의 특징
- 식별자(@Id)가 있다
- 엔티티 타입은 식별자가 있고 식별자로 구별할 수 있다
- 생명 주기가 있다
- 생성하고, 영속화하고, 소멸하는 생명 주기가 있다
- em.persist(entity)로 영속화한다
- em.remove(entity)로 제거한다
- 공유할 수 있다
- 참조 값을 공유할 수 있다. 이것을 공유 참조라 한다
값 타입의 특징
- 식별자가 없다
- 생명 주기를 엔티티에 의존한다
- 스스로 생명주기를 가지지 않고 엔티티에 의존한다. 의존하는 엔티티를 제거하면 같이 제거된다
- 공유하지 않는 것이 안전하다
- 엔티티 타입과는 다르게 공유하지 않는 것이 안전하다. 대신에 값을 복사해서 사용해야한다
- 오직 하나의 주인만이 관리해야 한다
- 불변(immutable) 객체로 만드는 것이 안전하다
'JPA 프로그래밍' 카테고리의 다른 글
Ch12. 스프링 데이터 JPA (0) | 2025.01.22 |
---|---|
Ch10. 객체 지향 쿼리 언어 (10.5 네이티브 SQL, 10.6 객체지향 쿼리 심화) (0) | 2025.01.21 |
Ch10. 객체지향 쿼리 언어 (10.4 QueryDSL) (0) | 2025.01.21 |
Ch10. 객체지향 쿼리 언어 (10.3 Criteria) (1) | 2025.01.20 |
Ch10. 객체지향 쿼리 언어 (10.1 객체지향 쿼리 소개, 10.2 JPQL) (0) | 2025.01.20 |