TroubleShooting

[TroubleShooting] InvalidDefinitionException

KJihun 2023. 8. 6. 02:20
728x90

 

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: 
Cannot construct instance of `org.springframework.data.domain.PageImpl` 
(no Creators, like default constructor, exist): cannot deserialize from Object value 
(no delegate- or property-based Creator)

 

따로 캡처는 못했지만 Redis로 Page를 Caching 할 때 발생한 에러다. `org.springframework.data.domain.PageImpl` 클래스에 기본 생성자가 없어서 발생한다고 했다.

 

어떻게 해야할 지 고민하다가 PageImpl 클래스를 상속받아 커스텀하여 사용하기로 했다.

 

@JsonIgnoreProperties(ignoreUnknown = true, value = {"pageable"})
public class PageResponse<T> extends PageImpl<T> {

    public PageResponse(@JsonProperty("content") List<T> content, @JsonProperty("page") int page,
                        @JsonProperty("size") int size, @JsonProperty("totalElements") long totalElements) {
        super(content, PageRequest.of(page, size), totalElements);
    }

    public PageResponse(Page<T> page) {
        super(page.getContent(), page.getPageable(), page.getTotalElements());
    }

    public PageResponse(List<T> content, Pageable pageable, long totalElements) {
        super(content, pageable, totalElements);
    }

}

 

이후 정상적으로 작동됐다.

하지만 캐싱할 때 왜 기본 생성자가 필요한지, 왜 PageImpl은 기본 생성자가 없는지 궁금해서 찾아봤다.

 

캐싱할 때 왜 기본 생성자가 필요한 이유

캐싱 할 때, 캐시 라이브러리가 객체를 생성하고 역직렬화할 때 기본 생성자를 호출하여 새로운 객체를 생성한 다음,

역직렬화된 데이터를 해당 객체에 채워넣는다고 한다.

 

PageImpl 클래스에 기본 생성자가 없는 이유
PageImpl은 페이징 정보를 필수적으로 가지도록 설계되어 있었다.

기본 생성자가 있다면 페이징 정보를 지정하지 않고 객체를 생성할 수 있기 때문에 기본 생성자가 없는 것이었다.