【发布时间】:2021-08-01 05:28:46
【问题描述】:
我已经在 AWS EC2 上部署了多租户 Spring Boot 应用程序。该代码在本地系统中运行良好,但在 docker run 在 aws ec2 中运行后应用程序失败并出现以下错误。
] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'orderReportListener' defined in URL [jar:file:/app-service.jar!/BOOT-INF/classes!/com/aic/autofluence/appservice/scheduler/kafkaReportListener/OrderReportListener.class]: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'reportFactoryImplData' defined in URL [jar:file:/app-service.jar!/BOOT-INF/classes!/com/aic/autofluence/appservice/scheduler/service/Impl/ReportFactoryImplData.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'orderReportRepository' defined in com.aic.autofluence.appservice.scheduler.repository.OrderReportRepository defined in @EnableJpaRepositories declared on TenantDatabaseConfig: Cannot create inner bean '(inner bean)#4293e066' 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)#4293e066': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' available
2021-05-10 18:58:57.081 INFO 1 --- [ main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'masterdb-persistence-unit'
2021-05-10 18:58:57.082 INFO 1 --- [ main] com.zaxxer.hikari.HikariDataSource : masterdb-connection-pool - Shutdown initiated...
2021-05-10 18:58:57.099 INFO 1 --- [ main] com.zaxxer.hikari.HikariDataSource : masterdb-connection-pool - Shutdown completed.
2021-05-10 18:58:57.103 INFO 1 --- [ main] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2021-05-10 18:58:57.124 INFO 1 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-05-10 18:58:57.147 ERROR 1 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of constructor in com.aic.autofluence.appservice.scheduler.service.Impl.ReportFactoryImplData required a bean named 'entityManagerFactory' that could not be found.
我的示例代码如下:
tenantConfig:EntityManagerFactory bean 本身无法识别。它在本地系统中运行良好,在 vm 中同样失败
@Configuration
@EnableTransactionManagement
@ComponentScan(basePackages = { "x.x.x.x.scheduler.repository", "x.x.x.x.scheduler.model" })
@EnableJpaRepositories(basePackages = {"x.x.x.x..scheduler.repository", "x.x.x.x..scheduler.service"},
entityManagerFactoryRef = "tenantEntityManagerFactory",
transactionManagerRef = "tenantTransactionManager")
public class TenantDatabaseConfig {
@Bean(name = "tenantJpaVendorAdapter")
public JpaVendorAdapter jpaVendorAdapter() {
return new HibernateJpaVendorAdapter ();
}
@Bean(name = "tenantTransactionManager")
public JpaTransactionManager transactionManager(@Qualifier("tenantEntityManagerFactory") EntityManagerFactory tenantEntityManager) {
JpaTransactionManager transactionManager = new JpaTransactionManager ();
transactionManager.setEntityManagerFactory(tenantEntityManager);
return transactionManager;
}
@Bean(name = "datasourceBasedMultitenantConnectionProvider")
@ConditionalOnBean(name = "masterEntityManagerFactory")
public MultiTenantConnectionProvider multiTenantConnectionProvider() {
return new DataSourceBasedMultiTenantConnectionProviderImpl();
}
@Bean(name = "currentTenantIdentifierResolver")
public CurrentTenantIdentifierResolver currentTenantIdentifierResolver() {
return new CurrentTenantIdentifierResolverImpl();
}
@Bean(name = "tenantEntityManagerFactory")
@ConditionalOnBean(name = "datasourceBasedMultitenantConnectionProvider")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
@Qualifier("datasourceBasedMultitenantConnectionProvider")
MultiTenantConnectionProvider connectionProvider,
@Qualifier("currentTenantIdentifierResolver")
CurrentTenantIdentifierResolver tenantResolver) {
LocalContainerEntityManagerFactoryBean emfBean = new LocalContainerEntityManagerFactoryBean ();
//All tenant related entities, repositories and service classes must be scanned
emfBean.setPackagesToScan("com.aic.autofluence.appservice");
emfBean.setJpaVendorAdapter(jpaVendorAdapter());
emfBean.setPersistenceUnitName("tenantdb-persistence-unit");
Map<String, Object> properties = new HashMap<>();
properties.put( Environment.MULTI_TENANT, MultiTenancyStrategy.DATABASE);
properties.put( Environment.MULTI_TENANT_CONNECTION_PROVIDER, connectionProvider);
properties.put( Environment.MULTI_TENANT_IDENTIFIER_RESOLVER, tenantResolver);
properties.put( Environment.DIALECT, "org.hibernate.dialect.MySQL5Dialect");
properties.put( Environment.SHOW_SQL, true);
properties.put( Environment.FORMAT_SQL, true);
properties.put( Environment.HBM2DDL_AUTO, "none");
emfBean.setJpaPropertyMap(properties);
return emfBean;
}
}
**MasterConfig: It is configured properly working fine**
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = {"x.x.x.x.mastertenant.model",
"x.x.x.x.mastertenant.repository"
},
entityManagerFactoryRef = "masterEntityManagerFactory",
transactionManagerRef = "masterTransactionManager")
public class MasterDatabaseConfig {
private static final Logger LOG = LoggerFactory.getLogger(MasterDatabaseConfig.class);
@Autowired
private MasterDatabaseConfigProperties masterDbProperties;
@Bean(name = "masterDataSource")
public DataSource masterDataSource() {
HikariDataSource hikariDataSource = new HikariDataSource ();
hikariDataSource.setUsername(masterDbProperties.getUsername());
hikariDataSource.setPassword(masterDbProperties.getPassword());
hikariDataSource.setJdbcUrl(masterDbProperties.getUrl());
hikariDataSource.setDriverClassName(masterDbProperties.getDriverClassName());
hikariDataSource.setPoolName(masterDbProperties.getPoolName());
// HikariCP settings
hikariDataSource.setMaximumPoolSize(masterDbProperties.getMaxPoolSize());
hikariDataSource.setMinimumIdle(masterDbProperties.getMinIdle());
hikariDataSource.setConnectionTimeout(masterDbProperties.getConnectionTimeout());
hikariDataSource.setIdleTimeout(masterDbProperties.getIdleTimeout());
LOG.info("Setup of masterDataSource succeeded.");
return hikariDataSource;
}
@Primary
@Bean(name = "masterEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean masterEntityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean ();
em.setDataSource(masterDataSource());
em.setPackagesToScan(new String[]{x,x,x,x...});
em.setPersistenceUnitName("masterdb-persistence-unit");
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter ();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(hibernateProperties());
LOG.info("Setup of masterEntityManagerFactory succeeded.");
return em;
}
@Bean(name = "masterTransactionManager")
public JpaTransactionManager masterTransactionManager(@Qualifier("masterEntityManagerFactory") EntityManagerFactory emf) {
JpaTransactionManager transactionManager = new JpaTransactionManager ();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor ();
}
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.put(org.hibernate.cfg.Environment.DIALECT, "org.hibernate.dialect.MySQL5Dialect");
properties.put(org.hibernate.cfg.Environment.SHOW_SQL, true);
properties.put(org.hibernate.cfg.Environment.FORMAT_SQL, true);
properties.put(org.hibernate.cfg.Environment.HBM2DDL_AUTO, "none");
return properties;
}
任何想法可能是什么问题?
谢谢
【问题讨论】:
-
有人对此有想法吗?
-
你的意思是在上面的“x.x.x.x..scheduler.repository”中的包路径中有两个句点。这可能刚刚发生在您编辑时,但只是检查。
-
@Atmas x.x.x.x.. 是包名因为我不允许暴露它,所以我只是放了一些随机数据,比如 x.x.x.x ......我问的问题与 bean 创建有关。如果您有任何想法,请发表评论吗?
-
@Atmas 关于编辑在这里不是问题。 bean 创建没有发生,我观察到的是在 TenantDatabaseConfig 类中,指向与 MasterDatabaseConfig 相关的 bean,它本身在 TenantDatabaseConfig 类中未被识别。如果对此有任何想法,请对此发表评论
-
我想知道这是否只是配置冲突的约定。你愿意用“entityManagerFactory”替换你的bean名称和引用它的“tenantEntityManagerFactory”的所有实例吗?这样,它与方法名称(即 entityManagerFactory)一致,并且与我在网上看到的其他示例一致。
标签: java spring spring-boot hibernate