작성
·
267
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으로 여기서는 정상적으로 나오는데, 어디서 문제가 있는지 모르겠습니다.
구글링을 해도 마땅한 답을 구할 수 없어서 질문 남깁니다!
답변 4
0
[추가 설명 / 참고용]
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
안녕하세요 danseung님!
말씀해주신 에러 해결 도와드리기 위해
#page, #size 값에 null이 저장되는 코드 상태로
Github Reposiory 링크 한 번 전달해주실 수 있을까요~??
그리고 null이 저장된다고 판단하신 출력값 또는 화면 캡쳐해서 같이 보여주세요!
저도 공유해주시는 Repository 활용해서 디버깅해보겠습니다!
Intellij 내부의 설정으로 인해 이런 차이가 발생했었군요!!
저도 몰랐던 사실인데 하나 배우고 갑니다👍
다른 사람들을 위해서 이렇게 해결방법도 공유해주셔서 정말 감사드려요!!
0
우선 key 속성을 설정하는 부분을 다음과 같이 파라미터 순서를 입력하도록 해서 문제를 해결하긴 했습니다.
@Cacheable(
...
key = "'boards:page:' + #p0 + ':size:' + #p1",
...
하지만 #page, #size와 같이 파라미터명을 직접 사용하면 왜 null로 지정되는지는 아직 모르겠습니다.
0
안녕하세요, 인프런 AI 인턴입니다. danseung님,
Cacheable key 값 설정 시 null이 들어가는 문제에 대해 궁금해하셨군요. 일부 다른 수강생들도 유사한 문제를 겪었으며, 이에 대한 답변을 드리도록 하겠습니다.
아래는 유사한 질문과 그에 대한 답변 링크입니다:
이 질문에서는 CacheManager를 설정하는 방법에 대한 논의가 있으며, 캐시 설정을 통해 키값의 구조를 어떻게 변경할 수 있는지에 대한 힌트를 얻을 수 있습니다.
이 질문에서는 페이징 처리와 같은 상황에서 Page 객체를 어떻게 캐싱할 수 있는지에 대한 논의가 있습니다. Cacheable 키에 대한 문제점을 해결하는 데 참고하실 수 있습니다.
추가 팁:
page
와 size
가 실제로 null인지 디버깅을 통해 확인해 보세요.저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
아 방금 해결했습니다!
이런 SpEL 표현식에서 메서드 파라미터를 제대로 인식하지 못하는 이유는, 런타임 시에 자바가 메서드의 매개변수 이름을 유지하지 않기 때문이었습니다.
해결 방법으로는
build.gradle 파일에 다음 옵션을 추가하거나,
인텔리제이 프로젝트 설정에서 직접 -parameters 옵션을 추가하거나,
Build and run using 설정을 Gradle 로 지정하면 되는 것 같습니다.
저는 보통 이 설정을 Intellij IDEA로 지정했었는데, 이것 때문에 파라미터명을 제대로 인식하지 못한 듯 합니다.
혹시 비슷한 에러를 겪고 계신 분들이 있을지도 몰라 해결 방법 작성해 놓겠습니다.
강의로 많은 도움 받고 있습니다 감사합니다!!