JPA

JPA 기본 값 타입

으엉어엉 2024. 8. 28. 18:05
728x90

JPA의 데이터 타입 분류

엔티티 타입

  • @Entity로 정의하는 객체
  • 데이터가 변해도 식별자로 지속해서 추적 가능
    • 예) 회원 엔티티의 키나 나이 값을 변경해도 식별자로 인식 가능

 

값 타입

  • int, Integer, String처럼 단순히 값으로 사용하는 자바 기본 타입이나 객체
  • 식별자가 없고 값만 있으므로 변경시 추적 불가
    • 예) 숫자 100을 200으로 변경하면 완전히 다른 값으로 대체

 

값 타입 분류

• 기본값 타입

  • 생명주기를 엔티티의 의존
  • 값 타입은 공유 X 
    • 회원 A 변경시 다른 회원 B의 변경이 일어나서는 안된다.

 

 

 

• 임베디드 타입(embedded type, 복합 값 타입)

  • 새로운 값 타입을 정의할 수 있음
  • JPA는 임베디드 타입이라함
  • 주로 기본값 타입을 모아서 만든 복합 타입이라고도함
  • int or Spring 같은 값타입 ( Entity가 아님)

 

 

 

 

임베디드 타입 사용법

  • @Embeddable: 값 타입을 정의하는 곳에 표시
  • @Embedded: 값 타입을 사용하는 곳에 표시
  • 기본 생성자 필수

 

임베디드 타입의 장점

  • 재사용
  • 높은 응집도
  • Period.isWork()처럼 해당 값 타입만 사용하는 의미 있는 메소 드를 만들 수 있음
  • 임베디드 타입을 포함한 모든 값 타입은, 값 타입을 소유한 엔티 티에 생명주기를 의존함 

 

Mapping만 해주면 된다.

 

 

 

임베디드 타입과 테이블 매핑

  • 임베디드 타입은 엔티티의 값일 뿐이다.
  • 임베디드 타입을 사용하기 전과 후에 매핑하는 테이블은 같다.
  • 객체와 테이블을 아주 세밀하게(find-grained) 매핑하는 것이 가능하다.
  • 잘 설계한 ORM 애플리케이션은 매핑한 테이블의 수보다 클래 스의 수가 더 많다.
  • 현업에서는 Value Type을 많이 쓰지는 않는다.

 

 

@AttributeOverride: 속성 재정의

ex) homeAddress, workAddress가 있다고 가정한다면 중복이 되게 되는데 그 때 사용할 수 있다.

 

 

값 타입과 불변 객체

• 컬렉션 값 타입(collection value type)

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

 

 

 

 

 

객체 타입의 한계

  1. 항상 값을 복사해서 사용하면 공유 참조로 인해 발생하는 부작용 을 피할 수 있다.
  2. 문제는 임베디드 타입처럼 직접 정의한 값 타입은 자바의 기본 타입이 아니라 객체 타입이다.
  3. 자바 기본 타입에 값을 대입하면 값을 복사한다.
  4. 객체 타입은 참조 값을 직접 대입하는 것을 막을 방법이 없다.
  5. 객체의 공유 참조는 피할 수 없다

 

 

 

불변 객체

  • 객체 타입을 수정할 수 없게 만들면 부작용을 원천 차단
  • 값 타입은 불변 객체(immutable object)로 설계해야함
  • 불변 객체: 생성 시점 이후 절대 값을 변경할 수 없는 객체
  • 생성자로만 값을 설정하고 수정자(Setter)를 만들지 않으면 됨
  • 참고: Integer, String은 자바가 제공하는 대표적인 불변 객체

 

 

 

Member class

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

@ElementCollection
@CollectionTable(name= "ADDRESS",joinColumns = @JoinColumn(name="MEMBER_ID"))
private List<Address> addressHistory = new ArrayList<>();

 

@ElementCollection , @CollectionTable 사용

데이터베이스는 컬렉션을 같은 테이블에는 저장 할 수 없다. 1:N으로 풀어서 별도의 테이블로 풀어야한다.

 

 

Member member = new Member();
member.setUsername("memberA");
member.setHomeAddress(new Address("homeCity","Street","10000"));
member.getFavoriteFoods().add("치킨");
member.getFavoriteFoods().add("피자");
member.getFavoriteFoods().add("족발");

member.getAddressHistory().add(new Address("old1","Street1","10000"));
member.getAddressHistory().add(new Address("old2","Street2","20000"));
em.persist(member);

 

 

 

 

값 타입 컬렉션의 제약사항

  • 값 타입은 엔티티와 다르게 식별자 개념이 없다.
  • 값은 변경하면 추적이 어렵다.
  • 값 타입 컬렉션에 변경 사항이 발생하면, 주인 엔티티와 연관된 모든 데이터를 삭제하고, 값 타입 컬렉션에 있는 현재 값을 모두 다시 저장한다.
  • 값 타입 컬렉션을 매핑하는 테이블은 모든 컬럼을 묶어서 기본 키를 구성해야 함: null 입력X, 중복 저장X

 

 

728x90

'JPA' 카테고리의 다른 글

JPQL  (0) 2024.08.30
JPA의 다양한 쿼리방법  (0) 2024.08.30
JPA 고아객체  (0) 2024.08.25
JPA 영속성 전이 CASCADE  (0) 2024.08.25
JPA 즉시 로딩과 지연 로딩  (0) 2024.08.25