spring - 多个数据源和多个配置文件
问题描述
我有两个配置文件(“autoContido”和“weblogic”),每个配置文件都有两个配置类,因为我使用了两个数据源。
我已将来自特定数据源的 bean 注释为 @Primary,而来自其他数据源配置类的 bean 不是 @Primary,但我以不同的方式命名它们。
我认为通过使用@Primary 注释不会出现像下面这样的错误,但我仍然得到它们。谁能帮我看看是什么问题?
"Parameter 0 of constructor in br.com.brb.maf.model.repository.impl.EmprestimoTelebancoRepositoryImpl required a single bean, but 2 were found:
- org.springframework.orm.jpa.SharedEntityManagerCreator#0: defined by method 'createSharedEntityManager' in null
- org.springframework.orm.jpa.SharedEntityManagerCreator#1: defined by method 'createSharedEntityManager' in null"
我尝试使用 @Primary 注释,但仍然收到错误 br.com.brb.maf.model.repository.impl.EmprestimoTelebancoRepositoryImpl 中的构造函数参数 0 需要单个 bean,但找到了 2 个
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
basePackages = {"br.com.brb.maf.model.pesquisa.repository"},
transactionManagerRef = "customMobileTransactionManager",
entityManagerFactoryRef = "mobileEntityManager")
@Profile("weblogic")
public class BanknetDatabaseConfiguration implements EnvironmentAware {
//ommited ...
@Value("${spring.datasource.mobile.jndi-name}")
private String mobileJndiName;
@Override
public void setEnvironment(Environment environment) {
this.jpaPropertyResolver = new RelaxedPropertyResolver(environment, SPRING_JPA_PROPERTIES);
this.dataSourcePropertyResolver = new RelaxedPropertyResolver(environment, SPRING_DATASOURCE);
}
@Bean(name = "customMobileTransactionManager")
public PlatformTransactionManager transactionManager(@Qualifier("mobileEntityManager") EntityManagerFactory emf) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
@Bean(name = "mobileDataSource")
public DataSource dataSource() {
final JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
dsLookup.setResourceRef(true);
DataSource dataSource = dsLookup.getDataSource(mobileJndiName);
return dataSource;
}
@Bean(name = "mobileEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
@Qualifier("mobileDatasource") DataSource dataSource) {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource);
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());
em.setPackagesToScan(new String[] {"br.com.brb.maf.model.pesquisa"});
return em;
}
Properties additionalProperties() {
Properties properties = new Properties();
properties.setProperty(HIBERNATE_HBM2DDL_AUTO,
jpaPropertyResolver.getProperty(HIBERNATE_HBM2DDL_AUTO, VALIDATE));
properties.setProperty(HIBERNATE_DIALECT, jpaPropertyResolver.getProperty(HIBERNATE_DIALECT));
properties.setProperty(HIBERNATE_DEFAULT_SCHEMA, jpaPropertyResolver.getProperty(HIBERNATE_DEFAULT_SCHEMA));
properties.setProperty(HIBERNATE_SHOW_SQL,
jpaPropertyResolver.getProperty(HIBERNATE_SHOW_SQL, Boolean.FALSE.toString()));
properties.setProperty(HIBERNATE_FORMAT_SQL,
jpaPropertyResolver.getProperty(HIBERNATE_FORMAT_SQL, Boolean.FALSE.toString()));
return properties;
}
}
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
basePackages = {"br.com.brb.maf.model.repository"},
transactionManagerRef = "customTransactionManager",
entityManagerFactoryRef = "entityManagerFactory")
@Profile("weblogic")
public class DatabaseConfiguration implements EnvironmentAware {
//ommited...
@Value("${spring.datasource.maf.jndi-name}")
private String mafJndiName;
@Override
public void setEnvironment(Environment environment) {
this.jpaPropertyResolver = new RelaxedPropertyResolver(environment, SPRING_JPA_PROPERTIES);
this.dataSourcePropertyResolver = new RelaxedPropertyResolver(environment, SPRING_DATASOURCE);
}
@Primary
@Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
@Qualifier("dataSource") DataSource dataSource) {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource);
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());
em.setPackagesToScan(new String[] {"br.com.brb.maf.model"});
return em;
}
@Primary
@Bean(name = "dataSource")
public DataSource dataSource() {
final JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
dsLookup.setResourceRef(true);
// DataSource dataSource =
// dsLookup.getDataSource(dataSourcePropertyResolver.getProperty(JNDI_NAME));
DataSource dataSource = dsLookup.getDataSource(mafJndiName);
return dataSource;
}
@Primary
@Bean(name = "customTransactionManager")
public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
Properties additionalProperties() {
Properties properties = new Properties();
properties.setProperty(HIBERNATE_HBM2DDL_AUTO,
jpaPropertyResolver.getProperty(HIBERNATE_HBM2DDL_AUTO, VALIDATE));
properties.setProperty(HIBERNATE_DIALECT, jpaPropertyResolver.getProperty(HIBERNATE_DIALECT));
properties.setProperty(HIBERNATE_DEFAULT_SCHEMA, jpaPropertyResolver.getProperty(HIBERNATE_DEFAULT_SCHEMA));
properties.setProperty(HIBERNATE_SHOW_SQL,
jpaPropertyResolver.getProperty(HIBERNATE_SHOW_SQL, Boolean.FALSE.toString()));
properties.setProperty(HIBERNATE_FORMAT_SQL,
jpaPropertyResolver.getProperty(HIBERNATE_FORMAT_SQL, Boolean.FALSE.toString()));
return properties;
}
}
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
basePackages = { "br.com.brb.maf.model.pesquisa.repository" })
@Profile("autoContido")
public class BanknetDatabaseConfigurationStandalone implements EnvironmentAware {
//ommited...
@Override
public void setEnvironment(Environment environment) {
this.jpaPropertyResolver = new RelaxedPropertyResolver(environment, SPRING_JPA_PROPERTIES);
new RelaxedPropertyResolver(environment, SPRING_DATASOURCE);
}
@Bean(name = "mobileDataSource")
@ConfigurationProperties(prefix = "spring.datasource.mobile")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "mobileEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
@Qualifier("mobileDataSource") DataSource dataSource) {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource);
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());
em.setPackagesToScan(new String[] {"br.com.brb.maf.model.pesquisa"});
return em;
}
Properties additionalProperties() {
Properties properties = new Properties();
properties.setProperty(HIBERNATE_HBM2DDL_AUTO,
jpaPropertyResolver.getProperty(HIBERNATE_HBM2DDL_AUTO, VALIDATE));
properties.setProperty(HIBERNATE_DIALECT, jpaPropertyResolver.getProperty(HIBERNATE_DIALECT));
properties.setProperty(HIBERNATE_DEFAULT_SCHEMA, jpaPropertyResolver.getProperty(HIBERNATE_DEFAULT_SCHEMA));
properties.setProperty(HIBERNATE_SHOW_SQL,
jpaPropertyResolver.getProperty(HIBERNATE_SHOW_SQL, Boolean.FALSE.toString()));
properties.setProperty(HIBERNATE_FORMAT_SQL,
jpaPropertyResolver.getProperty(HIBERNATE_FORMAT_SQL, Boolean.FALSE.toString()));
return properties;
}
}
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
basePackages = { "br.com.brb.maf.model.repository" })
@Profile("autoContido")
public class DatabaseConfigurationStandalone implements EnvironmentAware {
//ommited...
@Override
public void setEnvironment(Environment environment) {
this.jpaPropertyResolver = new RelaxedPropertyResolver(environment, SPRING_JPA_PROPERTIES);
new RelaxedPropertyResolver(environment, SPRING_DATASOURCE);
}
@Primary
@Bean(name = "dataSource")
@ConfigurationProperties(prefix = "spring.datasource.maf")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Primary
@Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
@Qualifier("dataSource") DataSource dataSource) {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource);
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());
em.setPackagesToScan(new String[] {"br.com.brb.maf.model"});
return em;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
Properties additionalProperties() {
Properties properties = new Properties();
properties.setProperty(HIBERNATE_HBM2DDL_AUTO,
jpaPropertyResolver.getProperty(HIBERNATE_HBM2DDL_AUTO, VALIDATE));
properties.setProperty(HIBERNATE_DIALECT, jpaPropertyResolver.getProperty(HIBERNATE_DIALECT));
properties.setProperty(HIBERNATE_DEFAULT_SCHEMA, jpaPropertyResolver.getProperty(HIBERNATE_DEFAULT_SCHEMA));
properties.setProperty(HIBERNATE_SHOW_SQL,
jpaPropertyResolver.getProperty(HIBERNATE_SHOW_SQL, Boolean.FALSE.toString()));
properties.setProperty(HIBERNATE_FORMAT_SQL,
jpaPropertyResolver.getProperty(HIBERNATE_FORMAT_SQL, Boolean.FALSE.toString()));
return properties;
}
}
@Repository
public class EmprestimoBanknetRepositoryImpl implements EmprestimoBanknetRepositoryCustom {
private EntityManager entityManager;
@Autowired
public EmprestimoBanknetRepositoryImpl(EntityManager manager) {
this.entityManager = manager;
}
@Override
public LocalDateTime ultimaDataPesquisa() {
String jpql = "Select distinct max(i.dataOcorrencia) from IndicioEmprestimoBanknet i ";
Query query = entityManager.createQuery(jpql);
return (LocalDateTime) query.getSingleResult();
}
}
错误:
15165 [main] WARN o.s.b.c.e.AnnotationConfigEmbeddedWebApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'emprestimoJobTelebancoScheduler': Unsatisfied dependency expressed through field 'telebancoJob'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'EmprestimoTelebancoJob' defined in class path resource [br/com/brb/maf/application/batch/emprestimo/telebanco/EmprestimoTelebancoConfiguration.class]: Unsatisfied dependency expressed through method 'emprestimoTelebancoJob' parameter 1; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'EmprestimoTelebancoJobStep' defined in class path resource [br/com/brb/maf/application/batch/emprestimo/telebanco/EmprestimoTelebancoConfiguration.class]: Unsatisfied dependency expressed through method 'step' parameter 1; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'emprestimoTelebancoReader': Unsatisfied dependency expressed through field 'service'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'emprestimoServiceImpl': Unsatisfied dependency expressed through field 'telebancoRepository'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'emprestimoTelebancoRepositoryImpl' defined in file [C:\Users\u840280\Desktop\SVN\MAF\backend\construcao\branches\DSV_1.0.7\fontes\target\classes\br\com\brb\maf\model\repository\impl\EmprestimoTelebancoRepositoryImpl.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'javax.persistence.EntityManager' available: expected single matching bean but found 2: org.springframework.orm.jpa.SharedEntityManagerCreator#0,org.springframework.orm.jpa.SharedEntityManagerCreator#1
15181 [main] INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'default'
15181 [main] INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'default'
15212 [main] INFO o.s.b.a.l.AutoConfigurationReportLoggingInitializer -
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
15228 [main] ERROR o.s.b.d.LoggingFailureAnalysisReporter -
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of constructor in br.com.brb.maf.model.repository.impl.EmprestimoTelebancoRepositoryImpl required a single bean, but 2 were found:
- org.springframework.orm.jpa.SharedEntityManagerCreator#0: defined by method 'createSharedEntityManager' in null
- org.springframework.orm.jpa.SharedEntityManagerCreator#1: defined by method 'createSharedEntityManager' in null
Action:
Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed
解决方案
我找到了答案。我只需要明确设置我将在 EmprestimoBanknetRepositoryImpl 中使用的 EnityManager。所以,最后,它必须像下面这样:
@Repository
public class EmprestimoBanknetRepositoryImpl implements EmprestimoBanknetRepositoryCustom {
private EntityManager entityManager;
@Autowired
public EmprestimoBanknetRepositoryImpl(@Qualifier("mobileEntityManagerFactory") EntityManager manager) {
this.entityManager = manager;
}
@Override
public LocalDateTime ultimaDataPesquisa() {
String jpql = "Select distinct max(i.dataOcorrencia) from IndicioEmprestimoBanknet i ";
Query query = entityManager.createQuery(jpql);
return (LocalDateTime) query.getSingleResult();
}
}
推荐阅读
- javascript - 通过 VueJS 中的 props 将动态数据传递给引导程序的模态
- javascript - 有没有办法在 VueJS 中缓存 API 响应
- java - 方法是否与对象一起实例化?
- django - docker-entrypoint-initdb.d 中的脚本 sql 未执行
- angular - 如何在Angular中为switch case编写单元测试用例?
- three.js - 如何在不使用 Threejs 的情况下使用 WebGL 加载 glb 文件
- java - 如何使用租户 ID、客户端 ID 和客户端密码连接和管理 Azure Data Lake Storage Gen2 中的目录和文件?
- python - 如何在给定网站中抓取表格?
- java - Java中的Csv到Json转换
- c# - 获取控件中 ViewModel 中使用的 BindableProperty 的值?