[ERROR]org.springframework.data.mapping.MappingException: Parameter /Name for argument of type [java.lang.String] not specified, and parameter name information not found in class file
스프링 부트 3.2 매개변수 이름 인식 문제
스프링 부트 3.2부터 매개변수의 이름을 인식하지 못하는 문제가 있다.
발생하는 예외
스프링 MVC 관련
java.lang.IllegalArgumentException: Name for argument of type [java.lang.String] not specified, and parameter name information not found in class file either.
스프링 핵심 원리 기본편 관련
No qualifying bean of type 'com.example.demo.MemberRepository' available: expected single matching bean but found 2: memoryMemberRepository,memberRepository
스프링 부트 3.2부터 자바 컴파일러에 -parameters 옵션을 넣어주어야 애노테이션의 이름을 생략할 수 있다.
주로 아래의 애노테이션을 사용할 때 문제가 발생한다.
@RequestParam, @PathVariable, @Autowired, @ConfigurationProperties
@RequestParam 관련
애노테이션에 username이라는 이름이 명확하게 있다. 문제 없이 작동한다.
@RequestMapping("/request") public String request(@RequestParam("username") String username) { ... } |
애노테이션에 이름이 없다. -parameters 옵션 필요
@RequestMapping("/request") public String request(@RequestParam String username) { ... } |
애노테이션도 없고 이름도 없다. -parameters 옵션 필요
@RequestMapping("/request") public String request(String username) { ... } |
@PathVariable 관련
애노테이션에 userId라는 이름이 명확하게 있다. 문제 없이 작동한다.
public String mappingPath(@PathVariable("userId") String userId) { ... } |
애노테이션에 이름이 없다. -parameters 옵션 필요
@RequestMapping("/request") public String request(@RequestParam String username) { ... } |
@Autowired 관련
MemberRepository를 구현한 빈이 여러개 있다면 다음 코드에서 MemberRepository를 주입 받을 때 변수 이름인 memberRepository를 통해서 memberRepository라는 이름의 스프링 빈을 찾는다. 하지만 매개변수 이름을 사용할 수 없기 때문에 이름으로 대상을 찾을 수 없다.
@Component public class MemberServiceImpl implements MemberService { private final MemberRepository memberRepository; @Autowired public MemberServiceImpl(MemberRepository memberRepository) { this.memberRepository = memberRepository; } } |
해결 방안1
애노테이션에 이름을 생략하지 않고 다음과 같이 항상 적어준다.
@RequestParam("username") String username
@PathVariable("userId") String userId
@Qualifier("memberRepository") MemberRepository memberRepository
해결 방안2
컴파일 시점에 -parameters 옵션 적용
1. IntelliJ IDEA에서 File -> Settings를 연다. (Mac은 IntelliJ IDEA -> Settings)
2. Build, Execution, Deployment → Compiler → Java Compiler로 이동한다.
3. Additional command line parameters라는 항목에 다음을 추가한다.
-parameters
4. out 폴더를 삭제하고 다시 실행한다. 꼭 out 폴더를 삭제해야 다시 컴파일이 일어난다.
해결 방안3(권장)
Gradle을 사용해서 빌드하고 실행한다.
참고로 이 문제는 Build, Execution, Deployment -> Build Tools -> Gradle에서
Build and run using를 IntelliJ IDEA로 선택한 경우에만 발생한다. Gradle로 선택한 경우에는 Gradle이 컴파일 시점에 해당 옵션을 자동으로 적용해준다.
해결방안 3번을 선택하시면 코드 변경없이 문제를 해결할 수 있습니다. 3번을 권장합니다.
자바를 컴파일할 때 매개변수 이름을 읽을 수 있도록 남겨두어야 사용할 수 있다.
컴파일 시점에 -parameters 옵션을 사용하면 매개변수 이름을 사용할 수 있게 남겨둔다.
스프링 부트 3.2 전까지는 바이트코드를 파싱해서 매개변수 이름을 추론하려고 시도했다.
하지만 스프링 부트 3.2 부터는 이런 시도를 하지 않는다.
인텔리 제이 빌드 툴 세팅 변경
상세 이유
Spring 6.1에서 변경된 Parameter Name Retention
Spring 6.1에서 변경된 Parameter Name Retention에 대해서 알아보고 어떻게 대처할 수 있는지 살펴봅니다
www.korecmblog.com