값 타입
📌 JPA의 데이터 타입 분류
🔎 엔티티 타입
@Entity로 정의하는 객체로 데이터가 변해도 식별자로 지속해서 식별/추적 가능한 타입이다.
🔎 값 타입
int, Integer, String처럼 단순히 값으로 사용하는 자바 기본 타입이나 객체를 말한다. 식별자가 없고 값만 있으므로 추적이 불가능하다.
✔ 값 타입 분류
1. 기본 값 타입
- 자바 기본 타입(int, double) : 생명 주기를 Entity에 의존
- 래퍼 클래스(Integer, Long)
- String
- 값 타입은 공유하면 안된다.
- 래퍼 클래스나 String 같은 특수한 클래스는 공유 가능한 객체이지만 변경은 안된다.
2. 임베디드 타입
3. 컬렉션 값 타입
📌 값 타입과 불변 객체
🔎 부작용(Side Effect)
값 타입은 항상 값을 복사해서 사용하기 때문에 여러 엔티티에서 공유하면, 부작용(Side effect)이 발생한다. 그 이유는 한 곳의 수정으로 공유한 모든 엔티티에서
수정이 발생하기 때문이다. 따라서, 값 타입은 공유하면 안 된다.
위 테스트를 보면 member와 member2가 공유하는 address를 member에서만 수정했는데 member2도 수정되었다.
🔎 해결책
공유해야 하는 객체를 재선언해서 사용
🔎 한계
위처럼 항상 값을 복사해서 사용하면 공유 참조로 인해 발생하는 부작용을 피할 수 있다. 하지만 값 타입과 달리 임베디드 타입과 같은 객체 타입은
컴파일 타임에 아무런 에러도 주지 않으므로, 참조 값을 직접 대입하는 것을 막을 방법이 없다.
🔎 불변 객체(Immutable object)
값 타입은 불변 객체로 설계하여 처음 생성한 이후에는 변경되지 않도록 한다.
수정자(setter)를 제거하거나 private으로 선언하면 된다.
(참고) Integer나 String은 자바가 제공하는 대표적인 불변 객체
📌 값 타입의 비교
값 타입은 인스턴스(참조값)가 달라도 그 안에 내용이 같으면 같은 것으로 봐야 한다.
- 동일성(identity) 비교 : 인스턴스의 참조 값을 비교 ('==' 사용)
- 동등성(equivalence) 비교 : 인스턴스의 값을 비교 (equals() 사용)
값 타입은 동등성 비교를 해야 한다.
🔎 equals() 구현
equals()의 기본 구현은 동일성 비교다.
따라서, 이를 오버라이딩하여 동등성 비교로 적절하게 재정의해야 한다.
이때, 기본으로 생성되는 재정의 코드를 사용하면 된다.
Reference:
https://www.inflearn.com/course/ORM-JPA-Basic/dashboard