티스토리 뷰

 

[Redis] HATEOAS와 @Cacheable - 2

[Redis] HATEOAS와 @Cacheable 이전 Redis 삽질기에서 해결법은 찾지 못 했으나 타협점을 찾았기 때문에 올린다 내가 의도 했던 것은 RestController 응답을 HATEOAS에 맞춰 ResponseEntity 또는 ResponseEntity..

ryumodrn.tistory.com

 

위 글에서 이어지는 글이다

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가 알아서 타입 추론해서 올바른 객체로 역직렬화를 수행하는 것이다

 

https://www.baeldung.com/jackson-linkedhashmap-cannot-be-cast

 

 

타입 추론을 하게끔 하는 방법을 몰랐기 때문에

JdkSerializationRedisSerializer를 이용해 저장과 반환에는 성공했었다

그러나 치명적인 단점으로 사람이 읽을 수 없다는 문제가 있었고 이를 해결하기 위해 알아보던 중 아래 글을 발견했다

 

Error during Deserialization of PageImpl : Cannot construct instance of `org.springframework.data.domain.PageImpl`

Issue is when using Spring cache with redis cache manager, not able to deserializer Spring Pageable response due to no default constructor The spring boot version used is 2.1.4.RELEASE Redis con...

stackoverflow.com

 

 

마지막 분께서 남겨주신 글을 참고해 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로 나타나지 않게 해 준다

 

Pageable 나오지마 이 자식아

 

Redis에 저장된 데이터의 일부분이다 key가 깔끔 지 못하고 더러운 이유는

customKeyGenerator에서 Class 이름 + Method 이름 + Parameter 형태로 키를 생성하기 때문이고

BoardSearchCondition이라는 검색용 요소들을 담고 있는 커스텀 객체, Pageable이 파라미터라서 길어졌다

이 부분은 추후 더 나은 방법을 찾게 된다면 개선해봐야겠다

 

 

 

HATEOAS + Cacheable + Readable Data

드디어 성공이다

댓글
링크
글 보관함
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Total
Today
Yesterday