inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

비전공자도 이해할 수 있는 Redis 입문/실전 (조회 성능 최적화편)

@Cacheable key 속성에서 page, size 파라미터값 null

318

danseung

작성한 질문수 2

0

BoardService.class

@Cacheable(
            cacheNames = "getBoards",
            key = "'boards:page:' + #page + ':size:' + #size",
            cacheManager = "boardCacheManager"
    )
    public List<Board> getBoards(int page, int size) {
        log.info("page={},size={}", page, size);
        Pageable pageable = PageRequest.of(page - 1, size);
        Page<Board> pageOfBoards = boardRepository.findAllByOrderByCreatedAtDesc(pageable);
        return pageOfBoards.getContent();
    }

BoardController.class

@GetMapping
    public List<Board> getBoards(
            @RequestParam(name = "page", defaultValue = "1") int page,
            @RequestParam(name = "size", defaultValue = "10") int size
    ) {
        log.info("page={}, size={}", page, size);
        return boardService.getBoards(page, size);
    }

#page, #size 값에 모두 null이 저장되는 것 같습니다.

위 코드에서처럼 BoardService.getBoards(), BoardController.getBoards() 두 메서드 전부 page, size 값을 로그로 출력해보니 각각 1, 10으로 여기서는 정상적으로 나오는데, 어디서 문제가 있는지 모르겠습니다.

구글링을 해도 마땅한 답을 구할 수 없어서 질문 남깁니다!

redis nosql query-tuning performance-tuning

답변 4

0

JSCODE 박재성

[추가 설명 / 참고용]

Redis 캐시 적용하면서 @Cacheable의 key에서

#page, #size가 null로 찍히는 문제는 많은 분들이 처음에 겪는 대표적인 이슈에요 ~

 

결론부터 말씀드리면 #page, #size 와 같이

SpEL (Spring Expression Language) 로 메서드 파라미터명을 지정하려면,

자바 컴파일 시점에 파라미터 이름 정보를 유지해줘야 해요 ~

즉, -parameters 옵션이 빠져 있으면 런타임 시점에 파라미터 이름을 인식하지 못해서

null이 저장됩니다 !

그 이유로, 인텔리제이 자체 자바 컴파일러는

기본적으로 컴파일 시점에 메서드의 파라미터 이름을 지워버려요 !

 

예를 들어 아래와 같은 메서드는

public List<IngredientsVO> getList(int page, int size)

컴파일 후에는 int arg0, int arg1 같은 식으로 이름이 사라져요 !

이렇게 되면 Spring EL에서는 #page, #size 이름을 인식 못 해서 null이 되는 거죠 !

 

이런한 이슈는 크게 2가지 해결방법이 있어요 !

첫번째 방법으로는 "IntelliJ 설정 변경"이에요 ~

[File] > [Settings] > [Build, Execution, Deployment] > [Build Tools] > [Gradle]

Build and run using → Gradle 로 변경

Run tests using → Gradle 로 변경

 

두번째 방법으로는 "build.gradle에 -parameters 추가"에요 ~

tasks.withType(JavaCompile) {

options.compilerArgs += "-parameters"

}

위와 같이 build.gradle에 설정 코드를 추가하신 뒤 빌드를 다시 해주시면 됩니다 :)

 

혹시나 위 두 해결 방법이 적용이 안 되신다면 우선 임시방안으로

아래와 같이 파라미터 순서로 접근하는 코드를 작성해보세요 !

@Cacheable(

cacheNames = "getIngredients",

key = "'ingredients:page:' + #p0 + ':size:' + #p1",

cacheManager = "ingredientCacheManager"

)

하지만 해당 방법은 파라미터 순서가 바뀔시 문제가 될 수 있으니

가급적 위 두가지 정석적인 방법으로 해결해보시는걸 권장드려요 ~

0

JSCODE 박재성

안녕하세요 danseung님!

 

말씀해주신 에러 해결 도와드리기 위해

#page, #size 값에 null이 저장되는 코드 상태로

Github Reposiory 링크 한 번 전달해주실 수 있을까요~??

 

그리고 null이 저장된다고 판단하신 출력값 또는 화면 캡쳐해서 같이 보여주세요!

저도 공유해주시는 Repository 활용해서 디버깅해보겠습니다!

5

danseung

아 방금 해결했습니다!

이런 SpEL 표현식에서 메서드 파라미터를 제대로 인식하지 못하는 이유는, 런타임 시에 자바가 메서드의 매개변수 이름을 유지하지 않기 때문이었습니다.

해결 방법으로는

  1. build.gradle 파일에 다음 옵션을 추가하거나,

tasks.withType<JavaCompile>() {
    options.compilerArgs.add("-parameters")
}
  1. 인텔리제이 프로젝트 설정에서 직접 -parameters 옵션을 추가하거나,

  2. Build and run using 설정을 Gradle 로 지정하면 되는 것 같습니다.

     

    image.png

     

저는 보통 이 설정을 Intellij IDEA로 지정했었는데, 이것 때문에 파라미터명을 제대로 인식하지 못한 듯 합니다.

혹시 비슷한 에러를 겪고 계신 분들이 있을지도 몰라 해결 방법 작성해 놓겠습니다.

강의로 많은 도움 받고 있습니다 감사합니다!!

2

JSCODE 박재성

Intellij 내부의 설정으로 인해 이런 차이가 발생했었군요!!

저도 몰랐던 사실인데 하나 배우고 갑니다👍

다른 사람들을 위해서 이렇게 해결방법도 공유해주셔서 정말 감사드려요!!

1

0515

와 저도 build를 Intellij IDEA로 지정하고 진행하다 같은 오류가 발생했는데

 

덕분에 해결했습니다 감사합니다

0

danseung

우선 key 속성을 설정하는 부분을 다음과 같이 파라미터 순서를 입력하도록 해서 문제를 해결하긴 했습니다.

    @Cacheable(
            ...
            key = "'boards:page:' + #p0 + ':size:' + #p1",
            ...

하지만 #page, #size와 같이 파라미터명을 직접 사용하면 왜 null로 지정되는지는 아직 모르겠습니다.

0

인프런 AI 인턴

안녕하세요, 인프런 AI 인턴입니다. danseung님,

Cacheable key 값 설정 시 null이 들어가는 문제에 대해 궁금해하셨군요. 일부 다른 수강생들도 유사한 문제를 겪었으며, 이에 대한 답변을 드리도록 하겠습니다.

아래는 유사한 질문과 그에 대한 답변 링크입니다:

1. CacheManager 설정 관련 질문

이 질문에서는 CacheManager를 설정하는 방법에 대한 논의가 있으며, 캐시 설정을 통해 키값의 구조를 어떻게 변경할 수 있는지에 대한 힌트를 얻을 수 있습니다.

2. 페이지 데이터 캐싱할때 질문

이 질문에서는 페이징 처리와 같은 상황에서 Page 객체를 어떻게 캐싱할 수 있는지에 대한 논의가 있습니다. Cacheable 키에 대한 문제점을 해결하는 데 참고하실 수 있습니다.

추가 팁:

  • 메소드의 파라미터가 제대로 전달되지 않아 캐시 키값에 null이 들어가는 경우가 있으므로 @Cacheable 어노테이션의 key 속성에서 사용하는 SpEL 표현식이 올바르게 지정되었는지 확인하세요.
  • 메소드에 전달되는 파라미터인 pagesize가 실제로 null인지 디버깅을 통해 확인해 보세요.
  • Spring Expression Language (SpEL)를 사용할 때 파라미터명이 정확히 적용되었는지 확인하세요.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

redis VS valkey

0

198

2

스프링 부트에 Redis 적용하기 질문

0

97

2

redis 적용을 위한 service 반환값

0

62

2

redis 사용으로 인한 비용

0

239

2

Redis를 적용했음에도 불구하고 조회 성능의 큰 차이가 없고 오히려 더 안좋은 조회속도를 보이는 것 같습니다.

0

144

3

Elastic Cache 에러

0

85

2

Elastic

0

74

2

AWS 리소스 삭제에 관하여

0

74

2

ec2안에서 pull 받는 이유가 뭔가요 ?

0

83

2

Nest.js + Redis 구현 문제

0

677

3

데이터를 안가져와요

0

72

2

Spring Boot 프로젝트에 Redis 셋팅 추가하기에서 13분 질문있습니다.

0

188

2

레디스 환경 셋팅 질문있습니다.

0

99

2

엘라스틱 서치와 레디스의 차이점을 알고 싶습니다.

0

262

2

-parameters

0

128

2

Redis vs Memcached

0

230

2

redis 를 compose 로 묶어준 이유가 궁금합니다.

0

155

2

k6의 결과 해석

0

257

2

Jackson2JsonRedisSerializer에 대한 궁금증

0

233

1

사용된 어노테이션에 관한 질문

0

146

1

Redis 사용 방식에 대해서 질문 있습니다

0

154

1

aws elasticcache redis 툴 접속.

0

219

1

Redis를 사용하는 이유

0

708

2

로컬에서 docker compose 명령어 실행 시

0

275

2