olrlobt
[Spring/Error] Name for argument of type, @PathVariable name 생략 에러 본문
java.lang.IllegalArgumentException: Name for argument of type [long] not specified,
and parameter name information not available via reflection.
Ensure that the compiler uses the '-parameters' flag.
@PathVariable로 URL에서 변수를 받아오는 예제에서 위와 같은 에러가 발생했다.
문제가 된 Contoller
@GetMapping("/{itemId}")
public String item(@PathVariable long itemId, Model model) {
Item item = itemRepository.findById(itemId);
model.addAttribute("item", item);
return "basic/item";
}
@PathVariable로 매핑된 변수와 파라미터 변수의 이름이 같아서 생략이 가능하다고 생각했다.
원인
해당 오류는 @PathVariable과 @RequestParam을 사용할 때, Spring MVC가 URL 경로 변수의 이름을 자동으로 인식하지 못해 발생하는 오류이다.
특히 스프링 부트에서 자동으로 파라미터 이름을 추론했을 때, 예상치 못한 결과를 가져오는 등의 문제를 해결하기 위해 스프링 부트 3.2 이후 버전에서는 파라미터 이름을 자동으로 추론하지 않도록 변경되었다.
해결방안
1. @PathVariable name 속성 지정
가장 간단하고 명확한 방법으로 권장되는 방법이다.
개발자의 의도를 명확히 할 수 있도록 이 방법을 사용하는 것이 좋다.
@GetMapping("/{itemId}")
public String item(@PathVariable("itemId") itemId, Model model) {
Item item = itemRepository.findById(itemId);
model.addAttribute("item", item);
return "basic/item";
}
2. -parameters 컴파일 옵션 사용
File > Setting > Build, Execution, Deployment > Compiler > Java Compiler에서
Additional command line parameters에 "-parameters"를 추가한다.
해당 옵션을 사용하면 컴파일러에서 메서드 파라미터의 실제 이름을 유지하여, 파라미터 이름 추론을 사용할 수 있다.
위와 같이 설정을 적용한 후, /out 폴더를 삭제해 주어야 프로젝트가 다시 컴파일되며 옵션이 적용된다.
3. 프로젝트 Gradle 빌드
File > Setting > Build, Execution, Deployment > Build Tools > Gradle에서 프로젝트 빌드를 Gradle로 설정한다.
Gradle을 사용하면 앞서 설명한 -parameters 옵션이 자동으로 적용되기 때문에 문제 해결이 가능하다.
참고