JPA의 데이터 타입을 크게 분류하면 엔티티 타입과 값 타입으로 나눌 수 있다.
엔티티 타입
@Entity로 정의하는 객체.
식별자(@Id)를 통해 지속해서 추적할 수 있음.
값 타입
int, Integer, String처럼 단순히 값으로 사용하는 자바 기본 타입이나 객체.
엔티티 타입과는 달리 식별자가 없어 추적할 수 없다.
임베디드 타입 (복합 값 타입)
새로운 값 타입을 직접 정의해서 사용하는 타입.
@Entity // 엔티티 타입
public class Member {
@Id
@GeneratedValue
private Long id;
@Embedded
private Period period;
}
@Embeddable // 값 타입 (임베디드 타입)
public class Period {
private LocalDate startDate;
private LocalDate endDate;
}
새로 정의한 값 타입들은 재 사용할 수 있고, 응집도도 매우 높다. (좀 더 객체지향적이고, 코드가 더 명확해질 수 있다.)
임베디드 타입을 사용하기 위한 어노테이션
@Embeddable: 값 타입을 정의하는 곳에 표시
@Embedded: 값 타입을 사용하는 곳에 표시
- 참고로 둘 중 하나는 생략해도 된다.
값 타입과 불변 객체
임베디드 타입 같은 값 타입을 여러 엔티티에서 공유하면 위험하다.
객체를 불변하게 만들면 값으 수정할 수 없으므로, 부작용을 원천 차단할 수 있다.
따라서 값 타입은 불변 객체로 설계해야 한다.
불변 객체도 결국 객체라, 인스턴스의 참조 값 공유를 피할 수 없다. 하지만 참조 값을 공유한다 해도 인스턴스의 값을 수정할 수 없으므로 부작용이 발생하지 않는다.
@Embeddable
public class Address {
private String city;
protected Address() {
}
public Address(String city) {
this.city = city;
}
public String getCity() {
return this.city;
}
}
위와 같이 생성자로만 값을 설정하고, 수정자 즉 Setter를 만들지 않으면 된다.
값 타입의 비교
자바가 제공하는 객체 비교는 2가지로
- 동일성 비교: 인스턴스의 참조 값을 비교 (==)
- 동등성 비교: 인스턴스의 값을 비교, equals()
값 타입은 동등성을 비교해야한다. 따라서 값 타입의 equals() 메소드를 재정의해야 한다.
값 타입의 eqauls() 메소드를 재정의할 때는 보통 모든 필드의 값을 비교하도록 구현한다.
cf) equals()를 재 정의하면 hashCode()도 재 정의하는 것이 안전하다.
'Application > JPA' 카테고리의 다른 글
[JPA] JPQL 객체지향 쿼리 심화 (0) | 2021.02.21 |
---|---|
[JPA] 지연 로딩 N+1 문제와, JPQL 페치 조인 (0) | 2021.02.21 |
[JPA] 영속성 전이 Cascade란?, 고아 객체 제거 OrphanRemoval란? (2) | 2021.02.21 |
[JPA] 프록시란? 지연로딩 vs 즉시 로딩란? (0) | 2021.02.21 |
[JPA] 영속성 컨텍스트란? (0) | 2021.02.21 |