JAVA/프로젝트

리팩토링: 캐시 적용 중 NPE, key, keyGenerator, 캐시 초기화, 검색기능 캐시

whyHbr 2024. 9. 17. 23:03
728x90
반응형
 @Cacheable(value = "ConsultPendingList", keyGenerator = "keyGenerator")
    @Transactional(readOnly = true)
    public PagedDto<ConsultPendingListResponse> getConsultPendingListResponse(
            Long propertyId,
            String search,
            String consultant,
            LocalDate preferredAt,
            int page,
            int size) {
        getPropertyId(propertyId);

위는 입력된 파리미터를 사용해 검색 기능을 구현한 메서드이다. 

 

@Bean
    public KeyGenerator keyGenerator() {
        return (target, method, params) -> {
            StringBuilder sb = new StringBuilder();
            sb.append(target.getClass().getSimpleName());
            sb.append(".").append(method.getName());
            for (Object param : params) {
                sb.append(".").append(param.toString());
            }
            return sb.toString();
        };
    }

이 keygenerator 를 사용하니 파라미터 미입력시,  NPE가 나와 

 

@Cacheable(value = "ConsultPendingList", key = "#propertyId")

propertyId를 키로 사용했다.

 

에러는 나오지 않으나, 

검색 필터가 안먹는 문제 발생. 

무슨 입력값을 적용하든 캐시에 저장된 내용이 나왔다. 

 

그래서 null을 허용하는 keyGenerator 를 작성

@Bean
public KeyGenerator customKeyGenerator() {
    return (target, method, params) -> {
        StringBuilder sb = new StringBuilder();
        sb.append(target.getClass().getSimpleName());
        sb.append(".").append(method.getName());

        if (params != null) {
            for (Object param : params) {
                sb.append(".").append(param != null ? param.toString() : "null");
            }
        } else {
            sb.append(".null"); // params가 null인 경우를 처리
        }

        return sb.toString();
    };
}

 

 

적용: 

@Cacheable(value = "ConsultPendingList", keyGenerator = "customKeyGenerator")
@Transactional(readOnly = true)
public PagedDto<ConsultPendingListResponse> getConsultPendingListResponse(
        Long propertyId,
        String search,
        String consultant,
        LocalDate preferredAt,
        int page,
        int size) 

 

이렇게 하니 파라미터 별로 캐시가 저장되어 검색 기능이 잘 작동했다.

 

 

문제 2:

 TTL이 끝나기 전에 상담이 등록된다면,

@Transactional
@CacheEvict(
        value = {"ConsultPendingList", "ConsultCompletedList"},
        key = "#propertyId")
public void createNewCustomerAddition(Long propertyId, NewCustomerAdditionRequest request) {
    Property property = getProperty(propertyId);

@CacheEvict 를 사용하여 ConsultPendingList 캐시를 삭제해줬다.

728x90