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 |