JPA - 값 타입, 기본값 타입, 불변 객체
JPA 데이터 타입 분류
- 엔티티 타입
1. @Entity로 정의하는 객체
2. 데이터가 변해도 식별자로 지속해서 추적 가능
3. ex) 회원 엔티티의 키나 나이 값을 변경해도 식별자로 인식 가능
- 값 타입
1. int, Integer, String 처럼 단순히 값으로 사용하는 자바 기본 타입이나 객체
2. 식별자가 없고 값만 있으므로 변경시 추적 불가
3. ex) 숫자 100을 200으로 변경하면 완전히 다른 값으로 대체
- 기본값 타입
1) 생명주기를 엔티티에 의존
ex) 회원을 삭제하면 이름, 나이 필드도 함께 삭제
2) 값 타입은 공유하면 안됨
ex) 회원 이름 변경시 다른 회원의 이름도 함께 변경되면 안됨
3) int, double 같은 기본 타입(primitive type) 은 절대 공유 X
4) 기본 타입은 항상 값을 복사함
5) Integer 같은 래퍼 클래스나 String 같은 특수한 클래스는 공유 가능한 객체이지만 변경 X
- 기본값 타입 종류
1. 자바 기본 타입(int, double)
2. 래퍼 클래스(Integer, Long)
3. String
- 임베디드 타입(embedded type, 복합 값 타입)
1. 새로운 값 타입을 직접 정의할 수 있음
2. JPA는 임베디드 타입이라 함
3. 주로 기본 값 타입을 모아서 만들어서 복합 값 타입이라고도 함
4. int, String 과 같은 값 타입
- 임베디드 사용 법
1. @Embeddable : 값 타입을 정의하는 곳에 표시
2. @Embedded: 값 타입을 사용하는 곳에 표시
3. 기본 생성자 필수
- 임베디드 타입의 장점
1. 재사용
2. 높은 응집도
3. Period.isWork()처럼 해당 값 타입만 사용하는 의미 있는 메소드를 만들 수 있음
4. 임베디드 타입을 포함한 모든 값 타입은, 값 타입을 소유한 엔티티에 생명주기를 의존함
- 임베디드 타입과 테이블 매핑
1. 임베디드 타입은 엔티티의 값일 뿐이다.
2. 임베디드 타입을 사용하기 전과 후에 매핑하는 테이블은 같다.
3. 객체와 테이블을 아주 세밀하게(find-grained) 매핑하는 것이 가능
4. 잘 설계한 ORM애플리케이션은 매핑한 테이블의 수보다 클래스의 수가 더 많음
5. 임베디드 타입의 값이 null 이면 매핑한 컬럼 값은 모두 null
- 객체 타입의 한계
1. 항상 값을 복사해서 사용하면 공유 참조로 인해 발생하는 부작용을 피할 수 있다.
2. 문제는 임베디드 타입처럼 직접 정의한 값 타입은 자바의 기본 타입이 아니라 객체 타입이다.
3. 자바 기본 타입에 값을 대입하면 값을 복사한다.
4. 객체 타입은 참조 값을 직접 대입하는 것을 막을 방법이 없다.
5. 객체의 공유 참조는 피할 수 없다.
- 불변 객체 (생성 시점 이후 절대 값을 변경할 수 없는 객체)
1. 객체 타입을 수정할 수 없게 만들면 부작용을 원천 차단.
2. 값 타입은 불변 객체(immutable object) 로 설계해야함
3. 생성자로만 값을 설정하고 수정자(Setter)를 만들지 않으면 됨
- 수정자를 private로 설정하는 것도 방법
4. 참고 : Integer, String은 자바가 제공하는 대표적인 불변 객체
- 값 타입의 비교
1. 값 타입 : 인스턴스가 달라도 그 안에 값이 같으면 같은 것으로 봐야함
2. 동일성(identity) 비교 : 인스턴스의 참조 값을 비교, == 사용
3. 동등성(equivalence) 비교 : 인스턴스의 값을 비교, equals() 사용
4. 값 타입은 a.equals(b)를 사용해서 동등성 비교를 해야 함
5. 값 타입의 equals() 메소드를 적절하게 재정의(주로 모든 필드사용)
출처 - https://www.inflearn.com/course/ORM-JPA-Basic