티스토리 뷰
위 글에서 이어지는 글이다
2편에서의 문제점은 GenericJackson2JsonRedisSerializer를 사용했을 때 발생하던 아래 에러다
Caused by: java.lang.ClassCastException:
class java.util.LinkedHashMap cannot be cast to class org.springframework.data.domain.Page
baeldung.com을 참고하면 상세한 이유를 알 수 있다
JSON의 object를 역직렬화 시 타입이 주어지지 않으면 기본적으로 LinkedHashMap으로 인식하고 역직렬화를 수행하는데
당연하게도 LinkedHashMap은 Page가 아니니까 ClassCastException이 뜨게 된다
타입을 알려주는 방법으로 ObjectMapper로 readValue를 수행하는 과정에 TypeReference를 직접 갈겨도 되지만
우리가 원하는 것은 일일이 작성하지 않고 ObjectMapper가 알아서 타입 추론해서 올바른 객체로 역직렬화를 수행하는 것이다
타입 추론을 하게끔 하는 방법을 몰랐기 때문에
JdkSerializationRedisSerializer를 이용해 저장과 반환에는 성공했었다
그러나 치명적인 단점으로 사람이 읽을 수 없다는 문제가 있었고 이를 해결하기 위해 알아보던 중 아래 글을 발견했다
마지막 분께서 남겨주신 글을 참고해 PageImpl을 감싸는 CustomPageImpl을 만들었고 진행해봤는데
ClassCastException은 뜨지 않았는데 대신 아래 코드 블록에 보이는 에러 로그를 만나게 됐다
Resolved [org.springframework.data.redis.serializer.SerializationException:
Could not read JSON: Cannot construct instance of
`org.springframework.data.domain.PageRequest`
(no Creators, like default constructor, exist):
cannot deserialize from Object value (no delegate- or property-based Creator)
일단 JsonCreator를 통해 ObjectMapper가 타입 추론은 할 수 있게 됐는데
PageImpl이 가지고 있는 속성 중 PageRequest는 모르겠다는 것이다
이 문제가 왜 나왔는가?
난 응답 과정에서 page를 통해 간단한 size, totalElements, totalPages, number만 반환한다
pageable은 반환할 필요 없기 때문에 저장 과정에서 빼버려도 되는 녀석이다
그런데 Redis에 저장된 데이터에는 pageable 형태로 저장된 데이터가 존재한다
필요도 없는 녀석 때문에 PageRequest를 추론하지 못해 발생한 문제이니 저장 과정에서 빼버리도록 한다
해결법은 간단하다
CustomPageImpl에서 pageable 정보를 가져오는 getPageable을 override 후 @JsonIngore로 나타나지 않게 해 준다
Redis에 저장된 데이터의 일부분이다 key가 깔끔 지 못하고 더러운 이유는
customKeyGenerator에서 Class 이름 + Method 이름 + Parameter 형태로 키를 생성하기 때문이고
BoardSearchCondition이라는 검색용 요소들을 담고 있는 커스텀 객체, Pageable이 파라미터라서 길어졌다
이 부분은 추후 더 나은 방법을 찾게 된다면 개선해봐야겠다
HATEOAS + Cacheable + Readable Data
드디어 성공이다
'Spring > Spring Data' 카테고리의 다른 글
[JPA] 간접 참조 연관 관계 EventListener로 삭제하기 - 2 (0) | 2022.10.02 |
---|---|
[JPA] 간접 참조 연관 관계 EventListener로 삭제하기 - 1 (0) | 2022.10.02 |
[Redis] HATEOAS와 @Cacheable - 2 (0) | 2021.12.22 |
[Redis] LocalDateTime Serialization / Deserialization 삽질기 - 2 (4) | 2021.12.22 |
[Redis] HATEOAS와 @Cacheable 같이 쓰기 (0) | 2021.10.02 |