헤르메스 LIFE

Resolved [org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction] 본문

Exception

Resolved [org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction]

헤르메스의날개 2023. 3. 31. 01:17
728x90

개발환경

Spring Boot 2.7.9

H2 2.1.214

p6spy 1.8.1

slf4j 1.7.36

lombok

devtools

postgresql

Spring Data JPA


Code 테이블에 save 하던 중 아래와 같은 오류가 발생했습니다.

특별한 Exception 도 발생하지 않고 commit 할 수 없다라는 경고 메시지만 보여집니다.

WARN  23-03-31 00:43:896[http-nio-9090-exec-1] org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver.logException[208]: - Resolved [org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction]

Code Entity 데이터

TCodeD(super=BaseEntity(isNew=true, crtId=admin, crtDt=null, mdfId=admin, mdfDt=null), pCd=MY_CODE, cd=MY_CODE, cdNm=MY_CODE, useYn=Y, sortSeq=0, wdOpt1=string, wdOpt2=string, wdOpt3=string, wdOpt4=string, wdOpt5=string, numOpt1=0, numOpt2=0, numOpt3=0, numOpt4=0, numOpt5=0, rmk=string)

느낌 상 Entity Class에서 뭔가 문제가 있는 것 같습니다.

문제의 Entity Class.

package octopus.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.Table;
import javax.validation.constraints.NotEmpty;

import org.hibernate.annotations.Proxy;
import org.springframework.util.Assert;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import octopus.backend.v1.dto.TCodeDDto;

@Entity // jpa entity임을 알립니다.
@Getter // getter를 자동으로 생성합니다.
@ToString(callSuper = true)
@NoArgsConstructor(access = AccessLevel.PROTECTED) // 인자없는 생성자를 자동으로 생성합니다. 기본 생성자의 접근 제어자가 불명확함. (access =
                                                   // AccessLevel.PROTECTED) 추가
// @AllArgsConstructor // 객체 내부의 인스턴스멤버들을 모두 가지고 있는 생성자를 생성 (매우 위험)
@Table(name = "T_CODE_D")
@IdClass(TCodeDPK.class)
@JsonIgnoreProperties({ "hibernateLazyInitializer", "handler" }) // Post Entity에서 User와의 관계를 Json으로 변환시 오류 방지를 위한 코드
@Proxy(lazy = false)
public class TCodeD extends BaseEntity {
    private static final long serialVersionUID = 1L;
    
    @Override
    public String getId() {
        return this.cd;
    }
    
    @Builder
    public TCodeD(String pCd, String cd, String cdNm, String useYn, Integer sortSeq, String rmk,
            String crtId, String mdfId) {
        Assert.hasText(pCd, "pCd must not be empty");
        Assert.hasText(cd, "cd must not be empty");
        Assert.hasText(cdNm, "cdNm must not be empty");
        Assert.hasText(crtId, "crtId must not be empty");
        Assert.hasText(mdfId, "mdfId must not be empty");
        
        this.pCd     = pCd;
        this.cd      = cd;
        this.cdNm    = cdNm;
        this.useYn   = useYn;
        this.sortSeq = sortSeq;
        this.rmk     = rmk;
        this.crtId   = crtId;
        this.mdfId   = mdfId;
    }
    
    /**
     * 상세 Code Update
     */
    public void updateCodeD(TCodeDDto tCodeDDto) {
        this.cdNm    = tCodeDDto.getCdNm();
        this.useYn   = tCodeDDto.getUseYn();
        this.sortSeq = tCodeDDto.getSortSeq();
        this.rmk     = tCodeDDto.getRmk();
    }
    
    /**
     * 상세 Code Update - 삭제
     */
    public void updateUseYn(TCodeDDto tCodeDDto) {
        this.useYn = tCodeDDto.getUseYn();
    }
    
    /**
     * 상위 코드
     */
    @Id // pk
    @NotEmpty
    @Column(nullable = false, unique = true, length = 50)
    private String pCd;
    
    /**
     * 코드
     */
    @Id // pk
    @NotEmpty
    @Column(nullable = false, unique = true, length = 50)
    private String cd;
    
    /**
     * 코드명
     */
    @NotEmpty
    @Column(nullable = false, length = 200)
    private String cdNm;
    
    /**
     * 사용여부
     */
    @NotEmpty
    @Column(length = 1)
    private String useYn;
    
    /**
     * 정렬순서
     */
    @NotEmpty
    @Column(length = 4)
    private Integer sortSeq;
    
    /**
     * 비고
     */
    @Column(length = 1000)
    private String rmk;
    
}

Integer 타입에는 @NotEmpty 를 사용하면 안됩니다. @NotNull 을 사용해야 합니다.

@NotBlank 또는 @NotEmpty Annotation은 반드시 String 필드만 사용합니다. 


 

또 하나의 방법은 초기값을 넣는 방법입니다.

    /**
     * Default 값을 넣을 수 있음.
     * insert 되기전 (persist 되기전) 실행된다.
     */
    @PrePersist
    public void prePersist() {
        this.useYn   = this.useYn == null ? "Y" : this.useYn;
        this.sortSeq = this.sortSeq == null ? 0 : this.sortSeq;
    }

https://hermeslog.tistory.com/696

 

[JpaSystemException] Resolved [org.springframework.orm.jpa.JpaSystemException: Null value was assigned to a property

개발환경 Spring Boot 2.7.9 H2 2.1.214 p6spy 1.8.1 slf4j 1.7.36 swagger2 2.6.1 lombok devtools postgresql JPA 아래와 같은 오류가 발생했습니다. INFO 23-03-18 11:39:785[http-nio-9090-exec-1] octopus.advice.ExceptionAdvice.dataAccessException

hermeslog.tistory.com

https://stackoverflow.com/questions/5982741/validation-error-no-validator-could-be-found-for-type-java-lang-integer

 

Validation error: "No validator could be found for type: java.lang.Integer"

I am working on a project with Spring why do I keep getting the following error? javax.validation.UnexpectedTypeException: No validator could be found for type: java.lang.Integer Here is my code:

stackoverflow.com

 

728x90