Skip to content

Repositories throws NoSuchBeanDefinitionException when looking up bean definitions in a parent-child context arrangement #2383

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
GnusinPavel opened this issue Jun 16, 2021 · 0 comments
Assignees
Labels
type: bug A general bug

Comments

@GnusinPavel
Copy link

GnusinPavel commented Jun 16, 2021

After upgrade to spring boot 2.4.5, faced with interesting issue. If project contains more than one repository for Entity, more than one ApplicatinContext, general and web for example, and a Controller with a parameter, than I got org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'anotherMyEntityDao' available. Application starts normally and after the first request I get exception:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'anotherMyEntityDao' available
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:863) ~[spring-beans-5.3.8.jar:5.3.8]
	at org.springframework.data.repository.support.Repositories.lambda$cacheFirstOrPrimary$4(Repositories.java:293) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at java.base/java.util.Optional.map(Optional.java:265) ~[na:na]
	at org.springframework.data.repository.support.Repositories.cacheFirstOrPrimary(Repositories.java:293) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.repository.support.Repositories.cacheRepositoryFactory(Repositories.java:113) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.repository.support.Repositories.populateRepositoryFactoryInformation(Repositories.java:93) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.repository.support.Repositories.<init>(Repositories.java:86) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.repository.support.DomainClassConverter.lambda$setApplicationContext$2(DomainClassConverter.java:113) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.util.Lazy.getNullable(Lazy.java:230) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.util.Lazy.get(Lazy.java:114) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.repository.support.DomainClassConverter.getConverter(DomainClassConverter.java:102) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.repository.support.DomainClassConverter.matches(DomainClassConverter.java:94) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.core.convert.support.GenericConversionService$ConvertersForPair.getConverter(GenericConversionService.java:664) ~[spring-core-5.3.8.jar:5.3.8]
	at org.springframework.core.convert.support.GenericConversionService$Converters.getRegisteredConverter(GenericConversionService.java:561) ~[spring-core-5.3.8.jar:5.3.8]
	at org.springframework.core.convert.support.GenericConversionService$Converters.find(GenericConversionService.java:545) ~[spring-core-5.3.8.jar:5.3.8]
	at org.springframework.core.convert.support.GenericConversionService.getConverter(GenericConversionService.java:261) ~[spring-core-5.3.8.jar:5.3.8]
	at org.springframework.core.convert.support.GenericConversionService.canConvert(GenericConversionService.java:146) ~[spring-core-5.3.8.jar:5.3.8]
	at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:127) ~[spring-beans-5.3.8.jar:5.3.8]
	at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:73) ~[spring-beans-5.3.8.jar:5.3.8]
	at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:53) ~[spring-beans-5.3.8.jar:5.3.8]
	at org.springframework.validation.DataBinder.convertIfNecessary(DataBinder.java:696) ~[spring-context-5.3.8.jar:5.3.8]
	at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:125) ~[spring-web-5.3.8.jar:5.3.8]
	at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121) ~[spring-web-5.3.8.jar:5.3.8]
	at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:170) ~[spring-web-5.3.8.jar:5.3.8]
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) ~[spring-web-5.3.8.jar:5.3.8]
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.3.8.jar:5.3.8]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894) ~[spring-webmvc-5.3.8.jar:5.3.8]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.8.jar:5.3.8]
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.8.jar:5.3.8]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1063) ~[spring-webmvc-5.3.8.jar:5.3.8]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.8.jar:5.3.8]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.8.jar:5.3.8]
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.8.jar:5.3.8]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:626) ~[tomcat-embed-core-9.0.46.jar:4.0.FR]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.8.jar:5.3.8]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.46.jar:4.0.FR]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.46.jar:9.0.46]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.8.jar:5.3.8]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.8.jar:5.3.8]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.8.jar:5.3.8]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.8.jar:5.3.8]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.8.jar:5.3.8]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.8.jar:5.3.8]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
	at java.base/java.lang.Thread.run(Thread.java:829) ~[na:na]

It happens due to two application contexts general, that contains repository bean definition and web context, that contains controller. After the first http request, Spring initialise and cache repositories to resolve entity parameters (I guess), and if there is more than one repository, Spring tries to determine primary bean. It uses BeanFactory from ConfigurableApplicationContext that belongs to web context and of course it doesn't contains Repository bean definition and throws an exception.

To clarify that situation look at example project, that demonstrates that issue. it contains a test that fails.

GnusinPavel pushed a commit to GnusinPavel/spring-data-commons that referenced this issue Jun 16, 2021
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jun 16, 2021
@christophstrobl christophstrobl removed the status: waiting-for-triage An issue we've not yet triaged label Oct 11, 2021
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Oct 11, 2021
@mp911de mp911de added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged labels Oct 12, 2021
@mp911de mp911de changed the title No bean named available if more than one Repository exists for the same Entity Repositories throws NoSuchBeanDefinitionException when looking up bean definitions in a parent-child context arrangement Oct 12, 2021
@mp911de mp911de added this to the 2.5.6 (2021.0.6) milestone Oct 12, 2021
mp911de pushed a commit that referenced this issue Oct 12, 2021
We now look up bean definitions for repositories using BeanFactory.getMergedBeanDefinition(…) to consider parent-child relationships across application contexts.

As we iterate through bean definitions considering ancestors we need to allow parent bean definitions. Previously, we obtained the bean definition from the child context and since the bean was inherited from the parent, the child context cannot provide a bean definition.

Closes #2383
Original pull request: #2384.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug A general bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants