ysk(0soo)
Lifealong
ysk(0soo)
전체 방문자
오늘
어제
  • 분류 전체보기 (238)
    • Java (50)
      • whiteship-java-study (11)
      • Java (28)
      • time (6)
    • Spring (68)
      • JPA (15)
      • Spring (1)
      • SpringBoot (1)
      • SpringMVC (6)
      • Spring Security (22)
      • Jdbc (1)
      • RestDocs (14)
      • log (6)
    • Kotlin (3)
    • Web (2)
      • nginx (1)
    • Database (14)
      • MySQL (5)
      • PostgreSQL (1)
      • SQL (1)
      • Redis (4)
    • C, C++ (0)
    • Git (1)
    • Docker (2)
    • Cloud (3)
      • AWS (3)
    • 도서, 강의 (0)
      • t5 (0)
    • 기타 (7)
      • 프로그래밍 (1)
    • 끄적끄적 (0)
    • CS (14)
      • 운영체제(OS) (2)
      • 자료구조(Data Structure) (9)
    • 하루한개 (12)
      • 우아한 테크코스-10분테코톡 (12)
    • 스터디 (12)
      • 클린 아키텍처- 로버트마틴 (2)
      • JPA 프로그래밍 스터디 (10)
    • 테스트 (34)
      • JUnit (19)
      • nGrinder (2)
      • JMeter (0)
    • Infra (3)
    • 프로그래머스 백엔드 데브코스 3기 (0)
    • 디자인 패턴 (3)
    • Issue (4)
    • system (1)
      • grafana (0)
      • Prometheus (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록
  • github

공지사항

인기 글

태그

  • UserDetailsService
  • 정규표현식
  • AccessDecisionManager
  • jpa
  • 가상 스레드
  • restdocs enum
  • querydsl
  • LocalDateTime
  • AccessDecisionVoter 커스텀
  • java
  • nginx basic auth
  • tree
  • AuthenticationException
  • 인가(Authorization) 처리
  • StructuredConcorrency
  • 동일성
  • 동시성 제어
  • 트랜잭션
  • restdocs custom
  • DataJpaTest
  • 구조화된 동시성
  • nGrinder
  • 동등성
  • scope value
  • VirtualThread Springboot
  • FilterSecurityInterceptor
  • mysql
  • junit5
  • node exporter basic auth
  • 가상 스레드 예외 핸들링

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
ysk(0soo)

Lifealong

Spring/JPA

JPA Entity의 Field Data Type은 primitive, Wrapper 중 어떤것을 사용해야 할까?

2022. 12. 10. 22:13

Jpa Entity Data Type

Entity의 filed Data Type을 Primitve로 지정해야 할까 Wrapper Type으로 지정해야 할까?


결론

 

1. PK에는 Long(Wrapper Class) 을 사용하자

  • Wrapper Class 를 사용함으로써 Null을 대입해놓을 수 있는데, 명시적으로 PK가 아직 할당되지 않았음을 의미할수 있다. 반면 primivite type은 null 을 표시할 방법이 없다
  • JPA에서 Wrapper 클래스가 Number의 하위 타입인 경우(int, long 등)에는 해당 값이 0인 경우에만 이를 새로운 엔티티라 판단한다.
    • 0이 아니라면, save 시 merge가 동작하여 select + insert 쿼리 2번을 실행하게 된다.

 

2. Null이 필요한 컬럼인지 생각하자

  • 데이터베이스에서는 Null이 필요한 경우도 있다.
    • 저장하는 컬럼이 비어있는 값을 어떻게 표현할 지, 0을 표현할지 null을 표현할지 선택해서 사용해야 한다.
    • 만약 null이 필요하다면 Wrapper Type을 사용하는 것이 좋다. Wrapper Type은 0도, null도 표현할 수 있기 때문이다.
  • 데이터의 null 여부를 판단할 수 있어야 한다.
    • 데이터의 null 여부를 판단할 수 있어야 한다 null 데이터도 가져올 수 있어야 할 때가 있기 때문이다.
    • null 데이터의 존재 자체를 문제로 말할 수 있지만, 경험상 실무 DB에는 null인 컬럼이 꽤 존재한다.
  • 소수 필드의 boxing-unboxing은 배제하자.
    • 컴퓨팅 능력이 충분히 저렴해지고 높아져서 크게 염려 안해도 된다.
    • boxing-unboxing 이슈는 반복문과 같이 사용될 때 발생한다.
  • 코딩 스타일의 일관성을 가져갈 수 있다.
  • 일부 @Ttransient 필드에 대해서는 사용하기도 한다.
  • https://stackoverflow.com/questions/2331630/entity-members-should-they-be-primitive-data-types-or-java-data-types
  • We recommend that you declare consistently-named identifier attributes on persistent classes and that you use a nullable (i.e., non-primitive) type.
  • https://docs.jboss.org/hibernate/orm/5.3/userguide/html_single/Hibernate_User_Guide.html#entity-pojo-identifier
  • 가장 일반적인 구현체인 Hibernate의 문서를 보면 명시적으로 non-primitive type의 사용을 권장한다.
  • id를 primitive type으로 하면 0과 null을 구분할 수 없다.
    • primitive type의 기본 값이 0이기 때문이다.

 


 

Primitive Type Wrapper Class
byte Byte
short Short
int Integer
long Long
float Float
double Double
boolean Boolean
char Character

 

Primitive TypeVSWrapper Class

  • Primitive Type : 변수를 선언하면 Stack 저장공간에 데이터가 저장됨,
    • 변수가 Stack 에 저장되고, 값 자체를 담고있음
  • Wrapper Class : 참조 변수는 Stack에 저장되고, 데이터는 Heap 영역에 저장된다

 

두 자료형의 차이점

  1. 값을 저장하는가(기본타입), 주소를 참조하는가(참조타입)
  2. jvm내부에서 메모리가 어디 영역에 저장되는가 (stack - 기본형이 저장됨, heap - 객체들이 저장됨)
  3. primitive Type은 null을 저장할 수 없다.

 

Primitive Type 의 장점

  • 공유참조문제가 없다 (하지만 Wrapper Class 도 불변 객체이다 )
  • 성능이 조금이라도 더 좋다 (아니 좋을것같다)
  • nullPointException 발생이 원천봉쇄된다 (null을 가리킬 수 없다.)

 

Wrapper Class 사용의 장점

  • 멀티스레드에서 사용할 수 있다
  • nullPointException 이 발생할수는 있지만
    • null 임을 표시할수 있다. 숫자0이 의미를 갖는 경우도 분명히 있기때문
  • 하지만 명시적으로 vaildataion 을 사용할 수 있다
    • @NonNull, @NotNull.. 등등

 

결론

Primitive Type을 사용하게 되면 null을 표현할 수가 없다.

Primitive Type을 사용하게 되면, 비어있단 값을 0으로 표현해야 하는데, 0이라는 값도 충분히 비지니스 로직에서 필요한 값일 수 있다.

  • 또한 Primitive Type으로 엔티티를 찾을 수 없다면 0을 써야하는게 최선 같지만 그럴 수 없다
  • 0이라는 값으로 실수로 초기화 할 수 있는 문제도 존재한다.

 

  1. PK에는 Long(Wrapper Class) 을 사용하자
    • Wrapper Class 를 사용함으로써 Null을 대입해놓을 수 있는데, 명시적으로 PK가 아직 할당되지 않았음을 의미할수 있다. 반면 primivite type은 null 을 표시할 방법이 없다
    • JPA에서 Wrapper 클래스가 Number의 하위 타입인 경우(int, long 등)에는 해당 값이 0인 경우에만 이를 새로운 엔티티라 판단한다.
      • 0이 아니라면, save 시 merge가 동작하여 select + insert 쿼리 2번을 실행하게 된다.

 

  1. Null이 필요한 컬럼인지 생각하자
    • 데이터베이스에서는 Null이 필요한 경우도 있다.
      • 저장하는 컬럼이 비어있는 값을 어떻게 표현할 지, 0을 표현할지 null을 표현할지 선택해서 사용해야 한다.
      • 만약 null이 필요하다면 Wrapper Type을 사용하는 것이 좋다. Wrapper Type은 0도, null도 표현할 수 있기 때문이다.
    • 데이터의 null 여부를 판단할 수 있어야 한다.
      • 데이터의 null 여부를 판단할 수 있어야 한다 null 데이터도 가져올 수 있어야 할 때가 있기 때문이다.
      • null 데이터의 존재 자체를 문제로 말할 수 있지만, 경험상 실무 DB에는 null인 컬럼이 꽤 존재한다.
    • 소수 필드의 boxing-unboxing은 배제하자.
      • 컴퓨팅 능력이 충분히 저렴해지고 높아져서 크게 염려 안해도 된다.
      • boxing-unboxing 이슈는 반복문과 같이 사용될 때 발생한다.
    • 코딩 스타일의 일관성을 가져갈 수 있다.
    • 일부 @Ttransient 필드에 대해서는 사용하기도 한다.
    • https://stackoverflow.com/questions/2331630/entity-members-should-they-be-primitive-data-types-or-java-data-types
  1. Not Null이고, 수량을 표현하는 속성일경우 (Item의 재고 수량 필드(stockCount, quantity) 등) primitive type을 사용해도 상관없다
    • Null 이 필요한 경우도 없고, 따로 입력해 주지 않으면 기본값을 0으로 지정해도 문제가 없기 때문)

 

 

실제 Hibernate 문서에는 다음과 같이 권고하고 있다.

  • https://docs.jboss.org/hibernate/orm/5.3/userguide/html_single/Hibernate_User_Guide.html#entity-pojo-identifier
  • We recommend that you declare consistently-named identifier attributes on persistent classes and that you use a nullable (i.e., non-primitive) type.
  • Persistent 클래스에 일관되게 명명된 식별자 속성을 선언하고 null이 가능한(즉, Primitive가 아닌) 유형을 사용하는 것이 좋습니다
저작자표시 비영리 (새창열림)

'Spring > JPA' 카테고리의 다른 글

Jpa 쿼리 파라미터 로그 확인방법 - With DataJpaTest p6spy  (1) 2022.12.17
영속성 전이(Cascade) ManyToOne 시 주의할점 - 상위 엔티티 삭제 문제  (1) 2022.12.15
Spring Data Jpa Cursor based Pagenation (커서 기반 페이지네이션) 예제 (JpaRepository 커서 기반 페이지네이션  (0) 2022.12.14
@NotNull vs @Column(nullable = false), JPA에서 INSERT 전에 Null 검사하는 방법  (0) 2022.12.09
JpaRepository에서 save시 select 쿼리가 먼저 실행되는 이유  (0) 2022.12.07
    'Spring/JPA' 카테고리의 다른 글
    • 영속성 전이(Cascade) ManyToOne 시 주의할점 - 상위 엔티티 삭제 문제
    • Spring Data Jpa Cursor based Pagenation (커서 기반 페이지네이션) 예제 (JpaRepository 커서 기반 페이지네이션
    • @NotNull vs @Column(nullable = false), JPA에서 INSERT 전에 Null 검사하는 방법
    • JpaRepository에서 save시 select 쿼리가 먼저 실행되는 이유
    ysk(0soo)
    ysk(0soo)
    백엔드 개발을 좋아합니다. java kotlin spring, infra 에 관심이 많습니다. email : kim206gh@naver.com github : https://github.com/devysk

    티스토리툴바