본문 바로가기

개발/JPA

[JPA 기본] 9. 값 타입

주요 개념

1. 임베디드 타입

2. 값 타입 컬렉션

 

JPA의 데이터 타입

1. 엔티티 타입 

- @Entity 애노테이션 붙는 객체

- 데이터 변해도 PK 사용하여 추적 가능. (예. 6번 학생의 키가 바뀌어도, 6번 학생은 찾을 수 있다.)

2. 값타입

- 자바 기본 타입, 객체 (int, Integer, String...)

- 식별자 없다. 값 변경시 추적 불가

- 예. 100 -> 200 으로 변경 

 

값타입 종류

1. 기본 값 타입 

- 기본 타입 (int, double) / 래퍼 클래스 (Ineger, Long) / String

   ** 래퍼 클래스나 String은 공유 가능하지만 (= 같은 주소값 가지지만) setter 제공하지 않아서 변경 불가. 

- 생명주기를 엔티티에 의존 (예. 회원 삭제시 나이 삭제됨)

- 공유 불가 (A 회원 이름 변경하여도, B 회원의 이름은 그대로)

2. 임베디드 타입 (복합 값 타입)

- int, String과 같은 값 타입. (= 변경시 추적 불가)

- 임메디드 타입을 사용하기 전/후에 매핑하는 테이블은 같다.

- 잘 만든 ORM 애플리케이션은 하나의 Entity에 많은 클래스를 가짐.

   (임베디드 타입별로 메서드 생성. 책임 분리 가능)

- 예. 회원의 homeAddresss는 City, Street, ZipCode

- 기본 생성자 필수

- 장점

  • 재사용 가능
  • 응집도 high
  • homAddress.hasUpdateHistory() 처럼 임베디드 타입 내부 메서드 관리 가능.  (객체 지향)

- 예제: 값타입>임베디드 타입 강의 5:28

// 값 타입 정의 
@Embeddable 
public class Address {
	private String city;
    // ...

// 값 타입 호출
@Entity
public class Member {

	@Embedded
	private Address homeAddress;
	// ...
}

** 주의

1) 엔티티간 같은 값 타입을 공유하면 안된다.

    -> 값 복사를 사용하자. 왜냐면, 값타입 공유는 하나 업데이트 시 다른 데도 영향 끼침)

2) 값 타입은 불변 객체로 만들자

  -> 값타입 공유를 막을 방법이 없다. 따라서 setter를 쓸 수 없도록  설정

2) 값타입은 equals 메서드를 사용하여 비교.

 -> equals 와 hashcode 함께 재정의

3. 컬렉션 값 타입

- 정의: 값타입을 컬렉션에 담아 쓰는 경우. 

- 예) Set, List

// Member 엔티티

@ElementCollection
@CollectionTable(name="FAVORITE_FOOD", joinColumns = @JoinColumn(name="MEBER_ID"))
@Column(name="FOOD_NAME")
private Set<String> favoriteFoods = new HashSet<>();

- 값타입 컬렉션은 영속성 전이 + 고아객체 제거 기능을 필수로 가진다. 

- 지연 로딩 전략 사용

- 값타입 컬렉션 수정시 새 객체를 넣어주거나 (set), remove/add 를 사용하여 수정

findMember.setHomeAddress(new Address("newCity", old.getStreet(), old.getZipCode()));

 

히스토리 관리가 필요 없을 때 값타입 컬렉션을 사용한다.