Ambiguous mapping. Cannot map '*' method 에러가 난다면 이 이슈도 확인해보자.
(특히 console build는 되는데 intellij에서 build가 안된다면 이 문제일 가능성이 높다.)
증상
intellij에 있는 kotlin plugin을 "1.3.0-release-IJ2018.2-1"으로 업데이트 했더니 잘 뜨던 spring에 문제가 생겨서 확인해봤다.
문제의 위치는 refundController의 expire 메소드였는데 이상하니 httpMethod가 EXPIRE인 function만 문제가 되었다.
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'refundController' method
public static org.springframework.hateoas.Resource com.titicacacorp.billing.domain.management.refund.controller.RefundController.expire$default(com.titicacacorp.billing.domain.management.refund.controller.RefundController,long,java.lang.String,int,java.lang.Object)
to {[/management/refunds/{refundId}],methods=[DELETE]}: There is already 'refundController' bean method
public org.springframework.hateoas.Resource com.titicacacorp.billing.domain.management.refund.controller.RefundController.expire(long,java.lang.String) mapped.
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1631)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:481)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.addCandidateEntry(DefaultListableBeanFactory.java:1314)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1280)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveMultipleBeans(DefaultListableBeanFactory.java:1178)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1094)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1064)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:835)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)
... 36 common frames omitted
Caused by: java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'refundController' method
에러를 보면 Ambiguous mapping으로 이미 어딘가에서 refundController의 expire 메소드를 이미 mapping 했다고 에러가 난 것이다.
처음에는 이것 때문에 매핑룰이 문제인가 해서 룰을 고쳐보았으나 해결되진 않았고 원인은 뜻하지 않는 곳에 있었다.
@DeleteMapping("/refunds/{refundId}")
fun expire(
@PathVariable refundId: Long,
@RequestParam(required = false) operation: String? = null
): Resource {
refundService.expire(refundId, operation)
return Resource(refundId)
}
expire 메소드에 대한 코드는 위처럼 생겼는데 문제가 생긴 부분은 뜬금없이 RequestParam이었다.http delete method의 경우 requestbody에 데이터를 보낼 수 없기 때문에 queryString으로 간단한 데이터를 전송하려고 만들었는데.. kotlin plugin 버전이 올라가면서 여기부분에 처리 문제가 생긴 듯 하다.
@RequestParam(required = false) operation: String? = null)
위 코드에서 null일 때 default 변수를 세팅하는 로직을 지우면 해결된다.
fun expire(
@PathVariable refundId: Long,
@RequestParam(required = false) operation: String?)
이렇게 말이다.
아마 plugin의 path가 진행되면 해당 문제도 사라질 것이지만 혹시나해서 글로 남긴다.
댓글 없음:
댓글 쓰기