🌿 기본 환경: IDE: STS4, Language: Java

 

 

JPA entity로 생성한 테이블에 trigger를 통해 데이터를 INSERT하고자 할 경우,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
DELIMITER //
 
CREATE TRIGGER tempSeqTrigger BEFORE INSERT ON tempUser
FOR EACH ROW
BEGIN
  DECLARE sequence_value INT;
  
  INSERT INTO tempSeq VALUES (NULL);
  SET sequence_value = LAST_INSERT_ID();
  SET NEW.id = CONCAT(NEW.type, LPAD(sequence_value, 6'0'));
END//
 
DELIMITER ;
 
 
 

🚨 다음과 같은 Error 발생

java.sql.SQLIntegrityConstraintViolationException: Column '...' cannot be null

 

 

발생 원인

INSERT 시, JPA에서 setId를 통해 PK값을 주입 전에 trigger가 실행되어 trigger에서 null exception을 발생시킴

* 실행순서 Trigger → JPA insert
트리거에서 NEW.user_id 값을 설정하려고 하지만, JPA는 이전에 생성된 userEntity 객체를 사용하여 저장을 시도하므로 user_id 컬럼이 null인 상태로 반환됨

 

 

해결 방법

@PrePersist를 사용하여 JPA를 통해 userEntity를 저장하기 전에 해당 컬럼에 값을 할당해야 함

1
2
3
4
5
6
    @PrePersist
    public void prePersist() {
        String uuid = UUID.randomUUID().toString();
        this.id = uuid;
    }
 
 
 

 

🟦 기본 환경: IDE: IntelliJ, Language: Java

 

 

SpringBoot의 MainApplication에서 양방향 참조 관계가 있는 Entity의 데이터를 호출할 경우,

🚨 다음과 같은 Error 발생

org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Infinite recursion (StackOverflowError)

 

 

발생 원인

Entity 객체간 양방향 참조관계가 있을 경우,  엔티티를 반환하여 JSON으로 변경할 경우, serialize(직렬화) 과정을 거치는데, 이때 객체간 상호 참조를 통해 무한 재귀 발생

 

 

해결 방법

1. 양방향 참조 관계의 필드에 @JsonIgnore 선언

🚨 해당 필드값이 null값으로 세팅되어 JSON으로 출력되지 않음

2. 부모 클래스측에 @JsonManagedReference를, 자식측에 @JsonBackReference를 Annotation에 추가

@JsonManagedReference
: 참조가 되는 앞부분을 의미, 정상적으로 직렬화를 수행
@JsonBackReference
: 참조가 되는 뒷부분을 의미, 직렬화를 수행하지 않음

3. Entity 대신 DTO를 만들어 return

 

 

 

참고 자료

 

[JPA] 스프링부트 Could not write JSON: Infinite recursion 에러 해결

에러 내용 Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Infinite recur

ahn3330.tistory.com

 

JPA에서 순환참조를 해결하는 방법 | @JsonIgnore, @JsonManagedReference, @JsonBackReference

JPA는 ORM이기 때문에 RDB를 관리하는데 있어서 양방향 참조를 필요로 한다. 물론 필수는 아니지만 Entity는 본질적인 데이터를 표현하는 것이기 때문에 그 관계에 대하여 명세해주는 것이 원칙이라

binarycube.tistory.com

 

20190720 [문제해결] Infinite recursion (StackOverflowError)

JPA 엔티티, JSON 변환 에러 org.springframework.http.converter.HttpMessageNotWritableException Could not write JSON Infinite recursion (StackOverflowError) nested exception is com.fasterxml.jackson.databind.JsonMappingException 원인 JPA 연관관

pasudo123.tistory.com

 

🟦 기본 환경: IDE: IntelliJ, Language: Java

 

 

SpringBoot의 MainApplication에서 다음 Source Code를 실행할 경우,

1
2
3
4
5
6
7
@GetMapping("/")
    public List<Item> list() {
        List<Item> items = itemStoryService.itemList();
        System.out.println(items)
        return items;
    }
 
 
 

🚨 다음과 같은 Error 발생

java.lang.StackOverflowError: null

 

 

발생 원인

@Data: 클래스의 Getter, Setter, equals(), hashCode(), toString() 등의 메서드를 자동으로 생성

클래스 내의 모든 필드를 포함한 문자열을 생성하기 위해 각 필드의 toString() 메서드를 호출

→ 클래스 내에 상호참조되는 관계가 있을 경우, 한 객체의 toString() 메서드에서 다른 객체의 toString() 메서드를 호출

→ 그 객체에서 다시 처음의 객체의 toString() 메서드를 호출(상호 참조 관계이므로)

→ 무한한 재귀 호출로 이어져 StackOverflowError가 발생

 

 

해결 방법

1. Entity의 @Data를 @Getter, @Setter로 수정

2. @ToString(exclude = "재 호출하는 entity 이름") 옵션 추가

 

 

정리

println() → valueOf() → toString() 호출

EntityA의 모든 필드에 대해 문자열화를 위해 필드로 선언된 EntityB의 toString 호출

→ EntityB의 toString()는 EntityB의 모든 필드에 대해 문자열화를 위해 필드로 선언된 EntityA의 toString 호출

→ 무한 반복

 

 

 

참고 자료

 

20. [JPA] lombok 사용 시 주의사항

엔티티 클래스에 lombok을 사용하면 StackOverflowError 오류가 발생할 수 있다. 다음과 같은 엔티티 연관 관계가 있다고 하자.12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535

lng1982.tistory.com

 

🟦 기본 환경: IDE: IntelliJ, Language: Java

 

 

발생 Error

SpringBoot에서 다음 Source Code를 실행할 경우,

검색 버튼 클릭 시, 🚨다음과 같은 Error 발생

org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: . near line 1, column 67 [select o from jpabook.jpashop.domain.Order o join o.member mwhereo.status = :statusandm.name like :name]; 

nested exception is java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: . near line 1, column 67 [select o from jpabook.jpashop.domain.Order o join o.member mwhereo.status = :statusandm.name like :name]

 

 

발생 원인

jpql 작성 시, ' ' 띄어쓰기 부재로 인한 구문의 부정확한 인식

 

해결 방법

관련 Controller에 action 주소 @PostMapping 메서드 추가

9행, 12행, 14행에서 구문 앞에 ' ' 띄어쓰기 추가

❌ Query문 작성 시, 띄어쓰기 유의

 

🟦 기본 환경: IDE: IntelliJ, Language: Java

 

 

발생 Error

SpringBoot에서 다음 Source Code를 실행할 경우,

🚨다음과 같은 Error 발생

Invocation of init method failed;
nested exception is org.hibernate.DuplicateMappingException: The [jpabook.jpashop.Member] and [jpabook.jpashop.domain.Member] entities share the same JPA entity name: [Member] which is not allowed!

 

 

발생 원인

동일한 Entity 이름(Member) 존재

 

 

해결 방법

Entity 이름의 중복을 피하기 위해서 EntityName을 따로 부여