I have looked at the following posts
1) Error creating bean with name 'requestMappingHandlerAdapter'
2)Spring Boot Ambiguous mapping. Cannot map method
3) Spring mvc Ambiguous mapping found. Cannot map controller bean method
4) Spring MVC Ambiguous mapping. Cannot map
But I have not been able to figure out how to resolve my issue. I am creating a Spring Boot web application in which I am trying to map the following endpoints /quiz/score/{quizId} and /quiz/questions/{quizId} endpoints to two separate methods.
My functions are as follows
#RequestMapping(name="/quiz/questions/{quizId}", method=RequestMethod.GET)
public ResponseEntity<QuizQuestion> questions(#PathVariable String quizId) {
QuizQuestion question = this.quizService.fetchQuestion(quizId);
if (question == null) {
return new ResponseEntity<QuizQuestion>(HttpStatus.NOT_FOUND);
}
return new ResponseEntity<QuizQuestion>(question, HttpStatus.OK);
}
and
#RequestMapping(name="/quiz/score/{id}", method=RequestMethod.GET)
public Score getScore(#PathVariable("id") String quizId) {
return this.quizService.getScore(quizId);
}
I am getting the following error
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 '/myapplication' method
public com.project.myapplication.Score com.project.myapplication.QuizController.getScore(java.lang.String)
to {[],methods=[GET]}: There is already '/myapplication' bean method
public org.springframework.http.ResponseEntity<com.project.myapplication.QuizQuestion> com.project.myapplication.QuizController.questions(java.lang.String) mapped.
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
. . . . . . . .. .
Caused by: java.lang.IllegalStateException: Ambiguous mapping. Cannot map '/myapplication' method
public com.project.myapplication.Score com.project.myapplication.QuizController.getScore(java.lang.String)
to {[],methods=[GET]}: There is already '/myapplication' bean method
public org.springframework.http.ResponseEntity<com.project.myapplication.QuizQuestion> com.project.myapplication.QuizController.questions(java.lang.String) mapped.
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping$MappingRegistry.assertUniqueMethodMapping(AbstractHandlerMethodMapping.java:576) ~[spring-webmvc-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at
I know that two methods have the same signature, but they have two unique endpoints. How can I resolve this issue?
Your problem is that you've specified your endpoints like this:
#RequestMapping(name="/quiz/score/{id}", method=RequestMethod.GET)
public Score getScore(#PathVariable("id") String quizId) {
return this.quizService.getScore(quizId);
}
But they should be like this:
#RequestMapping(value="/quiz/score/{id}", method=RequestMethod.GET)
public Score getScore(#PathVariable("id") String quizId) {
return this.quizService.getScore(quizId);
}
Note the value instead of name.
For further clarification, you can check RequestMapping javadoc, which explains the different parameters. name parameter just gives a name for your mapping. The value parameter is the key one.
Use value in place of name or you can use method Specific annotation
#GetMApping("/name")
#PostMApping("/name")
#PutMApping("/name")
#DeleteMApping("/name")
Related
#RepositoryRestResource(path = "/region", collectionResourceRel = "list", excerptProjection = CustomRegion.class)
public interface RegionRepository extends JpaRepository<Region, Integer> {
}
data rest class
#SpringBootApplication
public class ProfUzApplication {
public static void main(String[] args) {
SpringApplication.run(ProfUzApplication.class, args);
}
}
main running class
Occured error
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'repositorySearchController' defined in URL [jar:file:/C:/Users/saidk/.m2/repository/org/springframework/data/spring-data-rest-webmvc/3.2.1.RELEASE/spring-data-rest-webmvc-3.2.1.RELEASE.jar!/org/springframework/data/rest/webmvc/RepositorySearchController.class]: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityLinks' defined in class path resource [org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.rest.webmvc.support.RepositoryEntityLinks]: Factory method 'entityLinks' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'resourceMappings' defined in class path resource [org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.rest.core.mapping.RepositoryResourceMappings]: Factory method 'resourceMappings' threw exception; nested exception is java.lang.IllegalStateException: Path /region configured for uz.pdp.prof.repository.RegionRepository must only contain a single path segment!
You have to mention path='endpoint name' without using '/' in #RepositoryRestResource. You have to use #RepositoryRestResource(path = "region"), it's direct spring MVC to create RESTful endpoints at /region
The problem is happening because you defined the path using "/". Spring does not allow us to define a composed path like "/api/v1/my_entity". Just remove the "/" from your path and it will work.
I created a new project based on 2.2.2 a couple days ago and got the same issue.
After a few tries, the way to fix it is to use the same value in path and collectionResourceRel. In your case, try to use "region" in both path and collectionResourceRel.
This is my first post, so please excuse me if I miss to follow any convention of posting a good question.
I am coding a RESTful service using Spring REST. The signature of the service is as below.
#RestController
#RequestMapping(value = "/{param1}/{param2}/myservice", produces = MediaType.APPLICATION_JSON_VALUE)
public class MyService {
#RequestMapping(value = "/{param3}", method = GET)
public MyResponseObj getMyResponseDetails(MyRequestObject request){
//Service logic code
}
}
In above example, MyRequestObject contains a custom date object with a specific format. For the reference of this question, the name of the custom date object of MyDate in MyRequestObject is myDate.
My objective here is to convert the string value of myDate coming as a query parameter with name myDate. I have purposefully kept the query parameter name the same as of the inner object name within MyRequestObject class, so that Spring can implicitly assign the value to the myDate attribute of the MyRequestObject instance of the method argument. To make this auto assignment, I ensured to keep a constructor for MyDate with a String parameter. But, Spring does not do this auto-assignment for myDate value.
So, after reading several posts on this forum, I created a custom converter to convert a String object to MyDate object. Below is my code for the same.
#Component
public class StringToMyDateConverter implements Converter<String, MyDate> {
public MyDate convert(String s){
//MyDate.parseData(String) is a custom method to convert a String to MyDate object
return MyDate.parseData(s);
}
}
Then, I had added below configuration into my Spring config.xml file to add this custom converter class into Spring's default conversion service.
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.my.service.rest.util.conversion.StringToMyDateConverter"/>
</set>
</property>
</bean>
During application startup while debug, I have found that my custom converter code is getting executed and the Spring's default converter service registers my custom converter. However, I have also noticed that the Spring's internal code to initialize FormattingConversionServiceFactoryBean is getting executed multiple times during start up of the service. And that eventually resulted into overwriting of the converter service listing, which did not have my custom converter that got registered before.
So, when I invoke the REST service URL mentioned below, I get below mentioned error.
URL
http://localhost:7880/project/json/value1/value2/myservice/value3?myDate=2017-09-12
Exception
org.springframework.validation.BindException:
org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'request' on field 'myDate': rejected value [2017-09-12]; codes [typeMismatch.request.myDate,typeMismatch.myDate,typeMismatch.com.my.service.xml.datatype.MyDate,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [request.myDate,myDate]; arguments []; default message [myDate]]; default message [Failed to convert property value of type [java.lang.String] to required type [com.my.service.xml.datatype.MyDate] for property 'myDate'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [com.my.service.xml.datatype.MyDate] for property 'myDate': no matching editors or conversion strategy found]
It is important to mention here that my project has a complex module structure having multiple Spring configurations.
I think, because of that Spring is initializing the default conversion service multiple times. Though, I am not able to determine the order of configuration invocations so that I can prevent Spring overwriting my customer configuration added in the list. I have also tried the annotation based configuration class as listed below to achieve this result. But that also resulted in same issue.
#Configuration
public class ConversionServiceProvider {
#Autowired
private StringToMyDateConverter stringToMyDateConverter;
#Bean
public ConversionService getConversionService() {
ConversionServiceFactoryBean bean = new ConversionServiceFactoryBean();
bean.setConverters(getConverters());
bean.afterPropertiesSet();
ConversionService object = bean.getObject();
return object;
}
private Set<Converter<?, ?>> getConverters() {
Set<Converter<?, ?>> converters = new HashSet<>();
converters.add(stringToMyDateConverter);
// add here more custom converters, either as spring bean references or directly instantiated
return converters;
}
}
Can you please suggest me anything that I can try here to solve this issue? Please excuse me for the lengthy question, but I think that would help to understand the situation and problem better.
Thanks!!
I am trying to add a new Spring bean to one of my projects. The bean is defined and created in another package like so:
#Configuration
public class UtilityBeans {
public static String MY_BEAN_NAME = "my.bean.name";
#Bean(name = MY_BEAN_NAME)
public MyUtilBeanClass getMyBeanClass() {
return new MyUtilBeanClass();
}
}
I use it in my other package like this:
#Configuration
#Import({
UtilityBeans.class
)}
...
#Resource(name = UtilityBeans.MY_BEAN_NAME)
private MyUtilBeanClass myUtilBeans;
During runtime I get:
ERROR
Caused by: org.springframework.beans.factory.BeanCreationNotAllowedException: Error creating bean with name 'my.bean.name': Singleton bean creation not allowed while the singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)
...
The logs do not give me any useful information as the stack trace is all in Spring library. How can I find out what failed? Is it incorrect usage of resource or is it that the bean creation itself is wrong?
I am using Spring-4 with JDK8.
The issue here was that the bean was being created in 2 different points in my spring configuration due to some refactoring and the fix was to remove duplicate code. I had the same bean creation code:
#Bean(name = MY_BEAN_NAME)
public MyUtilBeanClass getMyBeanClass() {
return new MyUtilBeanClass();
}
... in another class I had half way refactored.
In this case my mistake was that I did not grep across all the log files being generated. The exceptions were being split and then buried into 2 different logs, one for a server start up and one for application runtime. The above exception was being posted to the application log. The other logs contained the relevant exception which stated that duplicate bean creation failed and the fix was to remove duplicate code.
I am totally new to Spring framework, bean injections etc, and working on a project organized in many sub-projects about it.
In the commons subproject, containing all Entities, DAOs, DS, I have a MyDS class implementing IMyDS and containing its EntityManager and DAO :
#PersistenceContext(unitName="myPersistenceUnit")
private EntityManager entityManager;
#Autowired
#Qualifier("myDAO")
private IMyDAO mainDao;
Then, I am trying to call this class from the Web part of my project, like this:
#Autowired
private IMyDS myDS;
// then I try to call a function of IMyDS, and get an error at this line :
protected ActionForward executeAction(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws ReefPresentationException {
myDS.callFunction(form);
}
But it doesn't work, giving me a NullPointerException. So far I've guessed the bean is not correctly injected, so I tried to add some information in my application-context-spring.xml file :
<bean id="myDS" class="com.my.project.service.IMyDS" />
And I get this error :
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myDS' defined in ServletContext resource [/WEB-INF/config/application-context-spring.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.my.project.service.IMyDS]: Specified class is an interface
So I tried instead to declare the class :
<bean id="myDS" class="com.my.project.service.internal.MyDS" />
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myDS' defined in ServletContext resource [/WEB-INF/config/application-context-spring.xml]: Instantiation of bean failed; nested exception is java.lang.ExceptionInInitializerError
So I really have no idea of what is wrong right now...
Thanks for your help
The errors says it all. You have defined your interface IMyDS as a bean and Spring can't instantiate the interface.
We have a sample app that showcases some things we are doing client side. It pulls in a few internal libraries to get everything functional. It dummies in some hard-coded data so it doesn't have to be concerned with any kind of persistence mechanism.
In some of these libraries that are pulled in, there are spring data jpa repositories. Something like this:
public interface MyLibraryEntityRepository extends JpaRepository<MyLibraryEntity, Long>
{
//...
}
When the server starts up, I get an error like this:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myLibraryEntityRepository': Cannot create inner bean '(inner bean)#788f64f1' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property 'entityManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#788f64f1': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' is defined
It can't find the entityManager, but I don't want to have to use an entityManager. So, in an attempt to override the myLibraryEntityRepository bean, I added the following to my Java config:
#Bean
public MyLibraryEntityRepository getMyLibraryEntityRepository()
{
return myDummyImpl();
}
However, this results in the same error.
Is there any way I can override the bean definition for the spring data jpa repository so that I can use my own dummy implementation and not have to configure an entityManager in my app?
You can use #Bean(name="dummyBean") and the in the #Autowired use the annotation #Qualifier("dummyBean")