오류 내용
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
'Springboot' 카테고리의 다른 글
[Gitignore X Springboot] 깃허브에 properties 파일 올리기 방지하기 (2) | 2023.06.16 |
---|---|
[Springboot] 일대다 관계 - @ManyToOne (0) | 2023.03.05 |
[Springboot] Entity와 DTO (0) | 2023.03.05 |
[Springboot] DB 데이터 생성/수정 날짜(시간) 자동 처리하기 (0) | 2023.03.05 |
[예약어 에러] You have an error in your SQL syntax; (1) | 2023.01.07 |