본문 바로가기

Spring/JPA

JPA Basic - 값 타입

1. 기본 값 타입

 ◍ JPA의 데이터 타입 분류

        엔티티 타입

           ◼  @Entity로 정의하는 객체

           ◼  데이터가 변해도 식별자로 지속해서 추적 가능

        값 타입

           ◼  int, Integer, String 처럼 단순히 값으로 사용하는 자바 기본 타입이나 객체

           ◼  식별자가 없고 값만 있으므로 변경시 추적 불가

◍ 값타입 분류

        기본 값 타입: 자바 기본 타입(int, double)/ 래퍼 클래스(Integer, Long)/ String

      ○  임베디드 타입: 복합 값타입

      ○  컬렉션 값타입

◍ 기본값 타입

        생명 주기를 엔터티에 의존

      ○  값 타입은 공유하면 안됨.

      ○  자바의 기본 차입은 절대 공유 불가.

           ◼  int,double같은 기본 타입은 절대 공유 못함

           ◼  기본 타입은 항상 값을 복사함.

           ◼  Integer같은 래퍼 클래스나 String 같은 특수한 클래스는 고융 가능 객체이지만 변경 불가하게 함.

 

2. 임베디드 타입

 

 ◍ 특징

       새로운 값 타입을 직접 정의할 수 있음

      ○ JPA는 embedded typedlfk gka

      ○ 주로 기본 값 타입을 모아서 복합 값 타입이라고도 함.  

◍  사용법

       @Embedable: 값 타입을 정의하는 곳에 표시

      ○ @Embedded: 값 타입을 사용하는 곳에 표시

      ○ 기본 생성자 필수

@Embeddable
public class period{

	private LocalDateTime startDate;
    private LocalDateTime endDate;

}

//사용 변수에 @Embedded 태그

 

◍ 장점

        재사용

        높은 응집도

        해당 값 타입만 사용하는 의미 있는 메소드 만들 수 있음

        임베디드 타입을 포함한 모든 값은, 값 타입을 소유한 엔티티에 생명주기를 의존함.

◍ 매핑

      ○  임베디드 타입은 엔티티의 값일 뿐 이다.

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

        객체와 테이블을 아주 세밀하게 매핑하는 것이 간으

        잘 설계한 ORM 애플리케이션은 매핑한 테이블의 수보다 클래스의 수가 더 많음.

        안에 엔티티도 들어올 수 있다. (연관 관계)

◍ @AttributeOverride: 속생 재정의

        한 엔티티 같은 임베디드 값 사용시. 

      ○  @AttributeOverrrides, @AttributeOverride 사용 컬럼명 속성 재 정의

◍ 임베디드 타입과 null

        임베디드 타입의 값이 null이면 매핑한 컬럼 값은 모두 null

 

3. 값 타입과 불변 객체

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

 ◍  값 타입 공유 참조

        임베디드 타입 같은 값 타입을 여러 엔티티에서 공유하면 부작용 발생

      ○  같이 쓰고 싶다면 엔티티로 만들어서 사용해야 한다. 

 ◍  값 타입 복사

        값 타입의 실제 인스턴스인 값을 공유하는 것은 위험

      ○ 대신 값(인스턴스)를 복사해서 사용

◍ 객체 타입의 한계

      ○  문제

           ◼   항상 값을 복사해서 사용하면 공유 참조로 인해 발생하는 부작용 피할 수 있다.

           ◼  문제는 임베디드 타입처럼 직접 정의한 값 타입은 자바의 기본 타입이 아니라 객체 타입

           ◼  자바 기본 타입에 값을 대입하면 값을 복사.

           ◼  객체 타입은 참조값을직접 대입하는 것을 막을 방법이 없다.

           ◼  객체의 공유 참조는 피할 수 없다. 

           ◼  ex> getter & setter

◍ 불변 객체 : 생성 시점 이후 절대 값을 변경할 수 없는 개체

        객체 타입을 수정 할 수 없게 하여 원천 차단.

      ○  방법

           ◼  생성자로 값을 설정하고 Setter를 만들지 않음. (예> Integer, String)

           ◼  setter로 값을 바꾸지 않고 새로 만들기. 

4. 값 타입의 비교

 ◍  값 타입: 인스턴스가 달라도 그 안에 값이 같으면 같은 것으로 봐야 함.

 ◍  비교

        동일성(identity) 비교: 인스턴스의 참조 값을 비교, == 사용

      ○  동등성(equivalence) 비교: 인스턴스의 값을 비교, equals() 사용

      ○  값 타입은 equals사용해 동등성 비교해야함 => 재정의 해야함 (기본이 == 이여서) + hashCode()도 같이 바꿔야 함. 

 

5. 값 타입  컬렉션

 ◍  사용이유

      ○  값 타입을 하나 이상 저장할때

      ○  @ElementCollection, @CollectionTable 사용

      ○  데이터베이스는 컬렉션을 같은 테이블에 저장할 수 없다.

      ○  컬렉션을 저장하기 위한 별도의 테이블이 필요함.   (Join)

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

 

 ◍ 제약사항

        값 타입은 엔티티와 다르게 식별자 개념이 없다. 

      ○  값은 변경하면 추적이 어렵다.

      ○  값 타입 컬렉션에 변경사항 발생시 주인 엔티티와 연관된 모든 데이터 삭제하고 값 타입 컬렉션의 현재 값 모두 다시 저장

      ○  값 타입 컬랙션을 매핑한 테이블은 모든 컬럼을 묶어서 기본 키 구성:" null 입력 안됨. 중복 저장 안됨.

 ◍ 대안

        실무에서는 상황 따라 값 타입 컬렉션 대신 일대다 관계를 고려

      ○ 일대다 관계 위한 엔티티 만들고 여기서 값 타입을 사용

      ○ 영속성 전이(Cascade) + 고아 객체 제거 사용해서 값 타입 컬렉션 처럼 사용.

 

엔티티 타입의 특정

 ◍ 식별자 있음

 ◍ 생명 주기 관리

 ◍ 공유

 

값 타입의 특징

 ◍ 식별자 없음

 ◍ 생명 주기를 엔티티에 의존

 ◍ 공유 하지 않는 것이 안전(복사)

 ◍ 불변 객체로 만드는 것이 안전

 

값 타입은 정말 값 타입이라 판단 될때만 사용. 엔티티와 값 타입을 혼동해서 엔티티를 값 타입으로 만들면 안됨. 식별자가 필요하고 지속해서 값을 추적, 변경 해야 한다면 그것은 값 타입이 아닌 엔티티.

'Spring > JPA' 카테고리의 다른 글

JPA Basics - JPQL Advanced  (0) 2024.01.10
JPA Basic - JPQL Basic  (0) 2024.01.10
JPA Basic - 프록시, CASCADE, 고아객체  (0) 2024.01.09
JPA Basic - 상속관계 매핑  (0) 2024.01.09
JPA Basic - 엔티티 매핑  (0) 2024.01.09