spring data jpa에서
No serializer found for class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor and no properties discovered to create BeanSerializer
에러가 발생했다.
간단하게 해석해보자면 serializer가 없다는 것인데,
serialize, 즉 직렬화란 간단히 말해서 Object를 연속된 String 데이터나 연속된 Bytes 데이터로 바꾸는 것을 의미한다.
역직렬화는 그 반대겠지?
Object는 메모리상에서 존재하고 추상적이다.
String 데이터나 Bytes 데이터는 드라이브에 저장될 수 있고 통신선을 통해 전송될 수 있다.
아무튼 다시 나는 스프링부트 + 코틀린을 사용하여 개발을 하고있었고,
JPA로 table을 findAll을 통해서 목록을 뽑아오는 기능을 구현하고있었다.
에러는 이 부분에서 발생했다.
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "category_id")
var noticeCategory: NoticeCategory,
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "board_id")
var noticeBoard: NoticeBoard
JPA로 조회한 데이터는 메모리 상에 존재하는 Object다
이 Object를 Json 형태로 반환하기위해 직렬화를 해주어야하는데
NoticeCategory와 NoticeBoard 컬럼이 LAZY로딩으로 설정되어있다.
이렇게 되면 조회한 Object를 serialize하려는 순간 실제 Object가 아닌
프록시로 감싸져있는 hibernateLazyInitializer를 serialize하게되므로 에러가 발생한다
해결
3가지 방법정도가 있다. 난 2번 방법을 사용했다.
1. @JsonIgnore로 반환시키지 않는다
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "category_id")
@JsonIgnore
var noticeCategory: NoticeCategory,
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "board_id")
@JsonIgnore
var noticeBoard: NoticeBoard
2. LAZY로딩 대신 EAGER로딩으로 설정해주면 된다
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "category_id")
var noticeCategory: NoticeCategory,
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "board_id")
var noticeBoard: NoticeBoard
3. application 파일에 spring.jackson.serialization.fail-on-empty-beans=false 설정해주면 된다
+
220328 추가사항
프록시 컬럼이 있는 엔티티를 그대로 반환하면 위에 보이듯 hibernateLazyInitializer를 직렬화하려다가 에러가났는데
ObjectMapper로 Entity -> dto로 변환을 시켜주니 LAZY로딩이 정상적으로 동작했다.
참고:
'삽질' 카테고리의 다른 글
postgres with docker compose gives FATAL: role "root" does not exist error (0) | 2023.04.20 |
---|---|
[AWS] Beanstalk의 .ebextensions 때문에 삽질한 썰 (0) | 2022.04.22 |
[에러] specify a path to the eslint package 해결 (0) | 2021.11.19 |