본문 바로가기

Springboot

[LAZY/EAGER 에러] No serializer found for class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor and no properties discovered to create BeanSerializer

오류 내용 

No serializer found for class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor 
and no properties discovered to create BeanSerializer 
(to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)

오류 번역

클래스 org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor에 대한 직렬 변환기가 
발견되지 않았고 BeanSerializer를 생성하기 위해 발견된 속성이 없다.
* 예외를 피하려면 SerializationFeature.FAIL_ON_EMPTY_BEANS를 비활성화라.

오류 원인

- 엔티티를 직렬변환 할 때, LAZY 조회로 비어있는 객체를 직렬변환하려고 해 발행하는 문제

- LAZY/EAGER에 대한 설명은 아래를 참조

해결 방법

1. application 파일에 spring.jackson.serialization.fail-on-empty-beans=false 설정해주기

2. 오류가 나는 엔티티의 LAZY 설정을 EAGER로 바꿔주기

3. 오류가 나는 컬럼에 @JsonIgnore를 설정해주기

LAZY (지연 로딩)

- 댓글 (One) 과 대댓글 (Many) 테이블

- Reply (대댓글) 엔티티에 @ManyToOne(fetch = FetchType.LAZY) 주목

// 댓글
public class Comment {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "comment_id")
    private Long commentId; // 기본키

    @OneToMany(mappedBy = "comment")
    private List<Reply> replys = new ArrayList<>(); // 대댓글 외래키 (일대다)
    
    private String comment; // 댓글 내용

}
// 대댓글
public class Reply {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "reply_id")
    private Long replyId; // 기본키

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "comment_id")
    private Comment comment; // 댓글 외래키 (다대일)

    private String reply; // 댓글 내용

}

- LAZY는 Reply만 조회해오고 연관관계에 있는 Comment 데이터는 조회하지 않는다. 

EAGER (즉시 로딩)

- 대댓글 (Many)의 @ManyToOne fetch 타입을 EAGER로 변경

- @ManyToOne 매핑의 기본 fetch는 EAGER이기 때문에 생략도 가능

// 대댓글
public class Reply {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "reply_id")
    private Long replyId; // 기본키

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "comment_id")
    private Comment comment; // 댓글 외래키 (다대일)

    private String reply; // 댓글 내용

}

- EAGER은 Reply뿐만 아니라 연관관계의 Comment 데이터도 조회한다. 

LAZY와 EAGER...언제 사용할까?

비지니스 로직 상 Reply (Many) 엔티티를 조회할 때 Comment (One)의 데이터도 필요하다면 EAGER로 함께 조회
비지니스 로직 상 Reply (Many) 엔티티를 조회할 때 Comment (One)의 데이터가 필요하지 않다면 LAZY 조회

내 코드 (오류 해결 전)

public class Scrap {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "scrap_id")
    private Long scrapId; // 기본키

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id")
    private User user; // 사용자 외래키 (다대일)

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "post_id")
    private Post post; // 글 외래키 (다대일)

}

- User 엔티티와 Post 엔티티를 Scrap 엔티티와 @ManyToOne으로 join 하는데 fetch 방법으로 LAZY를 선택해서 오류가 발생했다.

내  코드 (오류 해결 후)

public class Scrap {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "scrap_id")
    private Long scrapId; // 기본키

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "user_id")
    private User user; // 사용자 외래키 (다대일)

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "post_id")
    private Post post; // 글 외래키 (다대일)

}

 - LAZY를 EAGER로 수정하니 오류가 해결됐다. 

참고

 

[JPA]No serializer found for class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor and no properties discovered to creat

로직상으로는 요청을 받고 값을 가공해서 Map객체에 넣어준 후 Return만 하면 끝이라서 전혀 문제가 없어보였다. 허나 돌려보면 No SNo serializer found for class 이라는 오류가 계속 났다. 이유는 ManyToOne

csy7792.tistory.com

 

 

[JPA] 즉시로딩(EAGER)과 지연로딩(LAZY) (왜 LAZY 로딩을 써야할까?) (1)

이전 글에서 Proxy에 대해 살펴보았다. Proxy는 이 글의 주제인 즉시로딩과 지연로딩을 구현하는데 중요한 개념인데, 일단 원리는 미뤄두고 즉시로딩과 지연로딩이 무엇인지에 대해 먼저 알아보자

velog.io