JPA의 데이터 타입은 두 가지로 분류되는데 엔티티 타입과 값 타입으로 분류된다
엔티티 타입은 @Entity로 정의하는 객체로 식별자를 통해 지속적인 추적 가능하다
값 타입은 int, Integer, String 처럼 단순히 값으로 사용하는 자바 기본 타입이나 객체로 속성만 존재하므로 추적 불가능하다
값 타입은 다시 세 가지로 분류되는데 기본 값 타입, 임베디드 타입, 컬렉션 값 타입으로 분류된다
기본 값 타입
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
private String name;
private int age;
...
}
위의 예시에서 String, int가 값 타입이다
엔티티는 id라는 식별자 값도 가지고 생명주기도 있지만, 값 타입인 name, age 속성은 식별자 값도 없고 생명주기도 회원 엔티티에 의존한다
즉, 엔티티가 제거되면 속성 값도 제거된다
값 타입은 공유하면 안된다
임베디드 타입(복합 값 타입)
새로운 값 타입을 직접 정의해서 사용할 수 있는데 이를 임베디드 타입이라 한다
@Entity
public class Member {
@Id @GeneratedValue
private Long 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) {
// 값 타입을 위햔 메소드를 정의할 수 있다
}
...
}
회원이 상세한 데이터를 그대로 가지고 있는 것은 객체지향적이지 않으며 응집력만 떨어뜨린다
임베디드 타입은 재사용할 수 있고 응집도도 높다
임베디드 타입만 사용하는 의미 있는 메소드도 만들 수 있다 (Period.isWork())
@Embedded, @Embeddable을 이용해 임베디드 타입을 사용할 수 있다
- 둘 중 하나는 생략 가능하다
임베디드 타입을 포함한 모든 값 타입은 엔티티의 생명주기에 의존하므로 엔티티와 값 타입의 관계는 컴포지션(composition) 관계가 된다
임베디드 타입과 테이블 매핑
임베디드 타입은 엔티티의 값으로 임베디드 타입이 속한 엔티티 테이블에 매핑된다
임베디드 타입을 이용해 객체와 테이블을 세밀하게 매핑할 수 있다
임베디드 타입과 연관관계
임베디드 타입은 값 타입을 포함하거나 엔티티를 참조할 수 있다
@Entity
public class Member {
@Embedded Address address;
@Embedded PhoneNumber phoneNumber;
...
}
@Embeddable
public class PhoneNumber {
String areaCode;
String localNumber;
@ManyToOne PhoneServiceProvider provider; //엔티티 참조
}
@Entity
public class PhoneServiceProvider {
@Id String name;
...
}
@AttributeOverride: 속성 재정의
임베디드 타입에 정의한 매핑정보를 재정의하기 위해 사용한다
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
private String name;
@Embedded Address homeAddress;
@Embedded
@AttributeOverrides({
@AttributeOverride(name="city", column=@Column(name="COMPANY_CITY")),
@AttributeOverride(name="street", column=@Column(name="COMPANY_STREET")),
@AttributeOverride(name="zipcode", column=@Column(name="COMPANY_ZIPCODE"))
})
Address companyAddress;
}
하나의 엔티티 내에 같은 임베디드 타입을 여러 번 사용할 경우 컬럼명 중복이 발생하므로 매핑정보를 재정의해야 한다
임베디드 타입과 null
임베디드 타입이 null이면 매핑한 컬럼 값은 모두 null이 된다
'스터디 > JPA' 카테고리의 다른 글
객체지향 쿼리 언어 - (1) (0) | 2025.02.16 |
---|---|
값 타입 - (2) (0) | 2025.02.16 |
프록시와 연관관계 정리 - (3) (1) | 2025.02.14 |
프록시와 연관관계 정리 - (2) (0) | 2025.02.13 |
프록시와 연관관계 정리 - (1) (0) | 2025.02.13 |