// 에드센스

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 데이터는 드라이브에 저장될 수 있고 통신선을 통해 전송될 수 있다.

https://youtu.be/qrQZOPZmt0w

 

 

아무튼 다시 나는 스프링부트 + 코틀린을 사용하여 개발을 하고있었고,

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로딩이 정상적으로 동작했다.

 

참고:

+ Recent posts