ERD 설계시 Entity 타입은 개개인의 마음대로 primitive type를 받거나 하지만 오직 ID(PK값)만은 모두 Wrapper class로 Long을 선언한다.

type를 int로 설정해줘도 되는데, int도 아니고 Integer도 아니고 Long이다.

왜 그럴까?

먼저 Primitive type과 Wrapper class를 비교해보자.

  • Primitive type
    • 실제 값(data)를 저장한다
    • 객체지향적 언어는 아니다.
    • 성능이 좋다.
    • NPE를 피할 수 있다.(int든 long이든 0으로 잡아줌)
  • Wrapper class
    • 매개변수로 객체를 요구할 때 사용한다.
    • 객체간의 비교가 필요할 때 사용한다.
    • equual()가 오버라이딩 되어있어서 주소값이 아닌 객체가 가지고 있는 값을 비교한다.
    • Collections에서 오토박싱/언박싱을 해주지 않아도 되어서 편리하다.
    • NPE와 마주쳐야 한다. 그러나 primitive type과는 별개로, null을 피할 수 있는 방법이 생각외로 있다.

여기까지만 보면 primitive type을 쓰는 것이 좋을 수도 있다.
그러나 때로는 null을 표기해 주는것이 더 좋을때도 있다. Quantity같은 경우에서 '존재하지 않음'을 표시해야 하는데, primitive class에서는 '존재하지 않음'을 표기할 수가 없기 때문이다.
그러나 단순히 이렇게만 비교해서는 위와 같은 질문의 답을 얻기가 어렵다. 다음 차이점을 보자.

  • Primitive type
    • 선언시 stack 영역에 데이터가 저장된다.
  • Wrapper class
    • 실제 데이터는 Heap 영역에 저장되고, 레퍼런스가 stack에 생긴다.
    • immutable하다.
    • Primitive type는 매번 값을 복사하지만, Wrapper class는 레퍼런스만 복사한다.

여기서 힌트를 얻을 수 있다. JPA의 데이터 타입 분류에서 주의해야 할 점은 immutable한 type를 사용하고, 서로간에 값 타입이 공유되면 안된다고 배웠다. 그러나 래퍼 클래스는 레퍼런스만 복사되기 때문에 공유가 가능하지만 변경이 불가능해서 사용한다.
물론, 객체간 공유 참조는 피해야 한다.

int a = 20;
int b = a;
// 이 경우에는 값이 복사되지만

Integer a = new Integer(20);
Integer b = a;
// 이 경우에는 레퍼런스가 넘어간다.

이제 Wrapper 클래스를 id값의 type에 쓰는 이유는 대충 짐작을 했다. 그럼 왜 Integer가 아니라 Long일까?
id값은 대체적으로 데이터의 개수만큼 생성되는데, Integer값의 한계는 21억밖에 되지 않기 때문에 Long을 사용한다.

+ Recent posts