JPA

값 타입

dev-rootable 2023. 8. 18. 13:10

 

📌 JPA의 데이터 타입 분류

 

🔎 엔티티 타입

 

@Entity로 정의하는 객체로 데이터가 변해도 식별자로 지속해서 식별/추적 가능한 타입이다.

 

🔎 값 타입

 

int, Integer, String처럼 단순히 값으로 사용하는 자바 기본 타입이나 객체를 말한다. 식별자가 없고 값만 있으므로 추적이 불가능하다.

 

✔ 값 타입 분류

 

1. 기본 값 타입

 

  • 자바 기본 타입(int, double) : 생명 주기를 Entity에 의존
  • 래퍼 클래스(Integer, Long)
  • String
  • 값 타입은 공유하면 안된다.
  • 래퍼 클래스나 String 같은 특수한 클래스는 공유 가능한 객체이지만 변경은 안된다.

 

2. 임베디드 타입

 

3. 컬렉션 값 타입

 

📌 값 타입과 불변 객체

 

🔎 부작용(Side Effect)

 

값 타입은 항상 값을 복사해서 사용하기 때문에 여러 엔티티에서 공유하면, 부작용(Side effect)이 발생한다. 그 이유는 한 곳의 수정으로 공유한 모든 엔티티에서
수정이 발생하기 때문이다. 따라서, 값 타입은 공유하면 안 된다.

 

member와 member2는 address를 공유하고 있음

 

member2 CITY 값도 변경됨

 

위 테스트를 보면 member와 member2가 공유하는 address를 member에서만 수정했는데 member2도 수정되었다.

 

🔎 해결책

 

 

공유해야 하는 객체를 재선언해서 사용

 

동일한 내용의 Address의 참조 값을 나눠 부작용을 방지

 

변경을 시도한 member만 변경됨

 

🔎 한계

 

위처럼 항상 값을 복사해서 사용하면 공유 참조로 인해 발생하는 부작용을 피할 수 있다. 하지만 값 타입과 달리 임베디드 타입과 같은 객체 타입은
컴파일 타임에 아무런 에러도 주지 않으므로, 참조 값을 직접 대입하는 것을 막을 방법이 없다.

 

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

 

🔎 불변 객체(Immutable object)

 

값 타입은 불변 객체로 설계하여 처음 생성한 이후에는 변경되지 않도록 한다.

 

수정자(setter)를 제거하거나 private으로 선언하면 된다.

 

수정자 private 선언

 

(참고) Integer나 String은 자바가 제공하는 대표적인 불변 객체

 

📌 값 타입의 비교

 

값 타입은 인스턴스(참조값)가 달라도 그 안에 내용이 같으면 같은 것으로 봐야 한다.

 

  • 동일성(identity) 비교 : 인스턴스의 참조 값을 비교 ('==' 사용)
  • 동등성(equivalence) 비교 : 인스턴스의 값을 비교 (equals() 사용)

 

값 타입은 동등성 비교를 해야 한다.

 

🔎 equals() 구현

 

equals()의 기본 구현은 동일성 비교다.

 

equals() 기본 구현

 

따라서, 이를 오버라이딩하여 동등성 비교로 적절하게 재정의해야 한다.

 

이때, 기본으로 생성되는 재정의 코드를 사용하면 된다.

 

기본 재정의 코드

 

equals가 동등성 비교를 하도록 변경

 

Reference:

https://www.inflearn.com/course/ORM-JPA-Basic/dashboard

 

자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런 | 강의

초급자를 위해 준비한 [웹 개발, 백엔드] 강의입니다. JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자

www.inflearn.com