개발/spring

[jpa] @Id에 wraper 클래스만 사용해야하나?

방푸린 2024. 7. 3. 14:51
반응형

환경: springboot 2.7.6, mysql 8

 

@Id로 엔티티의 primitive key를 명시할 때 꼭 wrapper 클래스로 작성해야 하는지에 대한 의문이 생겼다.

wrapper클래스의 경우 null을 허용하는데, 엔티티를 저장할 때 키 값이 없으면(null) 자동 생성해 주는 기능 때문에 0이 의도치 않게 들어가면 이슈가 있을 수 있다고 생각했다.

하여 정리해본다.

 

id의 경우 아래와 같은 케이스가 있다.

  • select 시: id는 not null이기 때문에 굳이 wrapper를 쓸 일이 없음
  • insert 시:
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long seq;
  • jpa의 @GeneratedValue(strategy = GenerationType.IDENTITY)가 선언된 id 콜롬 & 디비에서 AUTO_INCREMENT 설정된 경우
    • 해당 경우는 디비의 설정을 사용한다는 뜻으로 mysql에 설정된 seq bigint(20) NOT NULL AUTO_INCREMENT COMMENT처럼 AUTO_INCREMENT 옵션이 들어간 경우 1부터 저장하기 때문에 0은 무시
  @Id
  private long seq;
  • @GeneratedValue 가 선언되지 않은 id 콜롬 & 디비에서 AUTO_INCREMENT 설정된 경우
    • 0 자체가 null과 동일하게 auto increment를 생성하라는 의미이기 때문에 0이 저장되지 않고 다음 sequence가 저장됨, AUTO_INCREMENT 옵션이 들어간 경우 1부터 저장하기 때문에 0은 무시
  • @GeneratedValue 가 선언되지 않은 id 콜롬 & 디비에서 AUTO_INCREMENT 설정되지 않은 경우
    • 0이 저장됨

참고로 mysql 기본 설정은 AUTO_INCREMENT일 때 0은 제외한다.
sql_mode항목에 NO_AUTO_VALUE_ON_ZERO 값이 설정되어 있으면 auto increment 시 0을 추가한다.

각자 디비에 어떻게 설정되어 있는지는 아래 쿼리로 확인 가능하며

SHOW VARIABLES LIKE 'sql_mode';

혹시.. 0을 의미 있는 값으로 세팅하려거든 아래처럼 하면 된다.

SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';

 

즉, id값을 primitive로 사용할지 wrapper로 사용할지에 대한 판단은, db에서의 0에 대한 설정과 값의 null/0 여부를 파악 후 결정하는 게 좋겠다

728x90
반응형