(예외) 중첩된 예외는 org.hibernate.id.IdentifierGenerationException입니다. 이 클래스의 ID는 save()를 호출하기 전에 수동으로 할당되어야 합니다.

개발 환경:

스프링 부트 2.7.9

데이터베이스: H2-2.1.214

JDK: 11.0.18 x64

JPA


DEBUG 23-03-11 00:39:202(http-nio-9090-exec-1) octopus.backend.v1.controller.CodeMController.save(55): - tCodeMDto :: TCodeMDto(pCd=null, pCdNm=null, useYn=null, rmk=null)
DEBUG 23-03-11 00:39:206(http-nio-9090-exec-1) octopus.backend.v1.service.CodeService.save(37): - tCodeMDto :: TCodeMDto(pCd=null, pCdNm=null, useYn=null, rmk=null)
INFO  23-03-11 00:39:211(http-nio-9090-exec-1) octopus.advice.ExceptionAdvice.dataAccessException(67): - (ExceptionAdvice >> dataAccessException) getMessage :: {errCode=-1, errMsg=ids for this class must be manually assigned before calling save(): octopus.entity.TCodeM; nested exception is org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): octopus.entity.TCodeM}
WARN  23-03-11 00:39:215(http-nio-9090-exec-1) org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver.logException(208): - Resolved (org.springframework.orm.jpa.JpaSystemException: ids for this class must be manually assigned before calling save(): octopus.entity.TCodeM; nested exception is org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): octopus.entity.TCodeM)

이 클래스의 ID는 save()를 호출하기 전에 수동으로 할당해야 합니다. @id 주석이 달린 생성자에 값을 할당하지 않아 발생하는 오류 보지 않았다.

@id는 pk를 의미하는 주석입니다. pk에 값이 없으면 당연히 잘못된 것입니다.

package octopus.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.Proxy;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity // jpa entity임을 알립니다.
@Getter // getter를 자동으로 생성합니다.
@Builder // builder를 사용할수 있게 합니다.
@NoArgsConstructor(access = AccessLevel.PROTECTED) // 인자없는 생성자를 자동으로 생성합니다.
@AllArgsConstructor(access = AccessLevel.PROTECTED) // 인자를 모두 갖춘 생성자를 자동으로 생성합니다.
@Table(name = "T_CODE_M")
@JsonIgnoreProperties({ "hibernateLazyInitializer", "handler" }) // Post Entity에서 User와의 관계를 Json으로 변환시 오류 방지를 위한 코드
@Proxy(lazy = false)
public class TCodeM extends BaseEntity {
    private static final long serialVersionUID = 1L;
    
    /**
     * 상위 코드
     */
    @Id // pk
    @Column(nullable = false, unique = true, length = 50)
    private String pCd;
    
    /**
     * 상위 코드명
     */
    @Column(nullable = false, length = 200)
    private String pCdNm;
    
    /**
     * 사용여부
     */
    @Column(nullable = false, length = 1)
    @Builder.Default
    private String useYn = "N";
    
    /**
     * 비고
     */
    @Column(length = 1000)
    private String rmk;
}
TCodeM tCodeM = TCodeM.builder().pCd(tCodeMDto.getPCd()).pCdNm(tCodeMDto.getPCdNm()).useYn(tCodeMDto.getUseYn())
                .rmk(tCodeMDto.getRmk()).build();
        
log.debug("tCodeM :: {}", tCodeM);

@Id가 적용되는 Java 유형

  • 자바 프리미티브
  • 자바 래퍼
  • java.util.날짜
  • java.sql.날짜
  • java.math.BigDecimal
  • java.math.BigInteger


https://ultrakain.gitbooks.io/jpa/content/chapter4/chapter4.6.html

4.6 기본 키 매핑 jpa

ultrakain.gitbooks.io