Spring-boot: Error when trying to bootstrap Hibernate asynchronously and using @EnableScheduling

Created on 31 Oct 2018  路  6Comments  路  Source: spring-projects/spring-boot

After upgrading application to Spring 2.1.0 I tried to use Hibernate asynchronously bootstrap, but when I'm adding a flag spring.data.jpa.repositories.bootstrap-mode=deferred to configuration then application throws error during startup:

Parameter 0 of method entityManagerFactory in org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration required a single bean, but 2 were found: - [ ] - applicationTaskExecutor: defined by method 'applicationTaskExecutor' in class path resource [org/springframework/boot/autoconfigure/task/TaskExecutionAutoConfiguration.class] - taskScheduler: defined by method 'taskScheduler' in class path resource [org/springframework/boot/autoconfigure/task/TaskSchedulingAutoConfiguration.class]

Looks like Spring have trouble with finding unique AsyncTaskExecutor bean and both beans are coming from auto configuration. To make it work I excluded TaskExecutionAutoConfiguration:

@SpringBootApplication(exclude = {TaskExecutionAutoConfiguration.class})
@EnableScheduling
class MyApp {}
bug

All 6 comments

Thanks for the report. Looks like we've missed testing the async bootstrapping with scheduling enabled.

I also get a similar error when using @EnableWebSocketMessageBroker. It looks like the JpaRepositoriesAutoConfiguration expects exactly one AsyncTaskExecutor in the application.

Cause:

org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.core.task.AsyncTaskExecutor' available: expected single matching bean but found 4: clientInboundChannelExecutor,clientOutboundChannelExecutor,brokerChannelExecutor,messageBrokerTaskScheduler
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:217)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1217)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory$DependencyObjectProvider.getIfAvailable(DefaultListableBeanFactory.java:1868)
    at org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration.lambda$entityManagerFactoryBootstrapExecutorCustomizer$0(JpaRepositoriesAutoConfiguration.java:76)
    at org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.lambda$entityManagerFactoryBuilder$0(JpaBaseConfiguration.java:128)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1378)
    at java.base/java.util.stream.SortedOps$RefSortingSink.end(SortedOps.java:395)
    at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258)
    at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
    at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
    at org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.entityManagerFactoryBuilder(JpaBaseConfiguration.java:128)
    at org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration$$EnhancerBySpringCGLIB$$b797f511.CGLIB$entityManagerFactoryBuilder$7(<generated>)
    at org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration$$EnhancerBySpringCGLIB$$b797f511$$FastClassBySpringCGLIB$$4837111.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:363)
    at org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration$$EnhancerBySpringCGLIB$$b797f511.entityManagerFactoryBuilder(<generated>)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
    ... 83 more

@trevor-stedman that's a related but it is a different problem. I suspect the fix on this issue will fix yours as well though.

Related issue in Spring https://jira.spring.io/browse/SPR-17021

Essentially the new auto-configuration in 2.1 configures a TaskScheduler and a TaskExecutor. Unfortunately, both are implementing the AsyncTaskExecutor interface so we could fix this issue by narrowing down the type that we require.

There's not much we can use without using a very specific type so I suggest we fallback to applicationTaskExecutor if more than one instance exists. This is the standard TaskExecutor bean name that is now promoted.

Was this page helpful?
0 / 5 - 0 ratings