SpringBoot多个数据源 - 在外部Tomcat容器中失败
我们正在使用springboot创建两个不同的数据源(microsoft sqlserver)。这在Eclipse Luna tomcat容器内正常工作。 当我们尝试在外部tomcat(8.0.x)容器中部署war文件时,失败并出现以下异常。
请告诉我们我们是否遗漏了任何配置,因为它在eclipse中正常工作
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'transactionManager' is defined
org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:698)
org.springframework.boot.autoconfigure.condition.OnBeanCondition.getPrimaryBeans(OnBeanCondition.java:237)
org.springframework.boot.autoconfigure.condition.OnBeanCondition.hasSingleAutowireCandidate(OnBeanCondition.java:230)
org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchOutcome(OnBeanCondition.java:102)
org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47)
org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:102)
org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader$TrackedConditionEvaluator.shouldSkip(ConfigurationClassBeanDefinitionReader.java:436)
org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:127)
org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:116)
org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:333)
org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:243)
org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:273)
org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:98)
org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:677)
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:519)
org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:667)
@Configuration
@EnableJpaRepositories(basePackages = "com.example.adapter.repository.first",
entityManagerFactoryRef = "entityManagerFactory", transactionManagerRef = "transactionManager")
@EntityScan("com.example.adapter.domain.first")
@EnableTransactionManagement
public class FirstDataSourceConfig {
@Primary
@Bean(name = "dataSource")
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource(){
return DataSourceBuilder.create().build()
}
@Primary
@Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(final EntityManagerFactoryBuilder builder) {
return builder
.dataSource(dataSource())
.packages("com.example.adapter.domain.first")
.persistenceUnit("first")
.build()
}
@Primary
@Bean(name = "transactionManager")
public PlatformTransactionManager transactionManager(@Qualifier("entityManagerFactory") EntityManagerFactory entityManagerFactory){
return new JpaTransactionManager(entityManagerFactory)
}
}
@Configuration
@EnableJpaRepositories(basePackages = "com.example.adapter.repository.second",
entityManagerFactoryRef = "secondEntityManagerFactory", transactionManagerRef = "secondTransactionManager")
@EntityScan("com.example.adapter.domain.second")
@EnableTransactionManagement
public class SecondDataSourceConfig {
@Bean(name = "secondDataSource")
@ConfigurationProperties(prefix = "datasource.second")
public DataSource secondDataSource(){
return DataSourceBuilder.create().build()
}
@Bean(name = "secondEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean secondEntityManagerFactory(final EntityManagerFactoryBuilder builder){
return builder
.dataSource(secondDataSource())
.packages("com.example.adapter.domain.second")
.persistenceUnit("secondPersistenceUnit")
.build()
}
@Bean(name = "secondTransactionManager")
public PlatformTransactionManager secondTransactionManager(@Qualifier("secondEntityManagerFactory") final EntityManagerFactory factory) {
return new JpaTransactionManager(factory)
}
}
spring.datasource.url: jdbc:sqlserver://XXXXX:1433;databaseName=XXXXX
spring.datasource.username: XXXXXX
spring.datasource.password: XXXXXX
spring.datasource.driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
datasource.second.url: jdbc:sqlserver://XXXXXX:1433;databaseName=XXXXXX
datasource.second.username: XXXXXX
datasource.second.password: XXXXXX
datasource.second.driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.jpa.properties.hibernate.show_sql: false
spring.jpa.properties.hibernate.dialect: org.hibernate.dialect.SQLServerDialect
@EnableCaching
@CompileStatic
@EnableScheduling
@SpringBootApplication
@EnableAutoConfiguration(exclude=[MultipartAutoConfiguration.class])
class MainApplication extends SpringBootServletInitializer{
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(MainApplication.class);
}
static void main(String[] args) throws Exception {
SpringApplication.run(MainApplication.class, args)
}
}
apply plugin: 'war'
providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")
configurations {
providedRuntime
}
答案 0 :(得分:0)
通过删除应用程序中@EnableAutoConfiguration的多次使用来解决问题。 我们注意到@EnableAutoConfiguration已经与MainApplication.java一起用在Swaggerconfig文件中,我们在Swaggerconfig文件中删除了。
现在应用程序在本地和外部tomcat中正常工作。
答案 1 :(得分:0)
尽管该解决方案适用于Windows操作系统中的本地和外部tomcat,但在Linux环境中失败。
Linux行为:
a)Tomcat不允许TransactionManager的自定义bean名称和@Primary数据源的EntityManagerFactory,如firstTransactionManager和firstEntityManagerFactory,因此强制使用bean名称作为transactionManager和entityManagerFactory。 [与具有外部tomcat容器的Windows操作系统相同] b)在将bean名称更改为TransactionManager和EntityManagerFactory之后,应用程序部署在Linux Tomcat中而没有任何失败,但始终在主数据源中执行查询并获取未找到表的错误,其中表中的第二个数据源的一部分
注意: - Tomcat版本为8.0.29,JDK版本为1.8.31,在Windows和Linux中都是相同的。
请告诉我们我们是否遗漏了任何配置,因为它在Windows Tomcat中正常运行。