문제 정의
spring boot와 redis를 활용해 cache 저장소를 구현하려고 할 때 발생했던 문제입니다.
@Cacheable(cacheNames = "itemCache", key = "args[0]")
public ItemDto readOne(Long id) {
log.info("Read One: {}", id);
return itemRepository.findById(id)
.map(ItemDto::fromEntity)
.orElseThrow(() ->
new ResponseStatusException(HttpStatus.NOT_FOUND));
}
@Cacheable(cacheNames = "itemAllCache", key = "methodName")
public List<ItemDto> readAll() {
return itemRepository.findAll()
.stream()
.map(ItemDto::fromEntity)
.toList();
}
@CachePut(cacheNames = "itemCache", key = "#result.id")
public ItemDto create(ItemDto dto) {
return ItemDto.fromEntity(itemRepository.save(Item.builder()
.name(dto.getName())
.description(dto.getDescription())
.price(dto.getPrice())
.build()));
}
코드를 보시게 되면 어떤 곳에서는 key에 args, methodName, #result.id를 사용하고 있는데요. 주의할 점이 key값에 #result를 사용한다면 메서드가 반환하기 전에 캐시가 설정되므로, 만약 메서드가 예외를 발생시키거나 반환값이 null이라면 캐시 키가 예상과 다르게 설정되거나 NullPointException이 발생할 수 있게 됩니다.
해결 과정
이 부분은 args 등을 사용해서 해결하면 되지만 위에서 언급했듯이 반환값이 없으면 null이 들어갈 수도 있겠구나..라는 생각을 미리 머리속에 담아두는 것이 앞으로는 필요할 것 같습니다.
'트러블 슈팅' 카테고리의 다른 글
gateway에서의 FeignClient 사용 (0) | 2024.12.18 |
---|---|
gateway에서 exchange를 사용하여 값을 전달할 때 주의점 (1) | 2024.12.18 |
gateway와 각 서버별 circuitbreaker 적용의 이해 (1) | 2024.12.18 |
@ModelAttribute 매핑 시 null값에 대한 이해 (0) | 2024.12.18 |
MSA 구성 시 데이터 정합성의 문제 (0) | 2024.12.18 |