In xml format, you can define some code as below to set two data sources without problems:
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
</bean>
<bean id="dataSource" class="com.zangland.routing.RoutingDataSource">
<property name="targetDataSources">
<map key-type="com.zangland.routing.DbType">
<entry key="MASTER" value-ref="dataSourceMaster"/>
<entry key="REPLICA" value-ref="dataSourceReplica"/>
</map>
</property>
<property name="defaultTargetDataSource" ref="dataSourceMaster"/>
</bean>
if I try to convert it in java like this, it will make error
@Configuration
@EnableJpaRepositories(entityManagerFactoryRef = "masterEntityManager", transactionManagerRef = "masterTransactionManager")
public class DataSourceConfiguration {
@Bean(name = "masterEntityManager")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(){
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan(new String[] {"com.zangland"});
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalJpaProperties());
em.setPersistenceUnitName("master");
return em;
}
@Bean(name = "masterTransactionManager")
public JpaTransactionManager transactionManager(EntityManagerFactory masterEntityManager){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(masterEntityManager);
return transactionManager;
}
@Bean
public RoutingDataSource dataSource() {
RoutingDataSource dataSource = new RoutingDataSource();
Map<Object, Object> dataSourceMap = new HashMap<Object, Object>();
dataSourceMap.put(DbType.MASTER, dataSourceMaster());
dataSourceMap.put(DbType.REPLICA, dataSourceReplica());
dataSource.setTargetDataSources(dataSourceMap);
dataSource.setDefaultTargetDataSource(dataSourceMaster());
dataSource.afterPropertiesSet();
return dataSource;
}
and the error will be here as below:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'masterEntityManager' defined in class path resource [com/zangland/routing/DataSourceConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean]: Factory method 'entityManagerFactory' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [com/zangland/routing/DataSourceConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.zangland.routing.RoutingDataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSourceMaster' defined in class path resource [com/zangland/routing/DataSourceConfiguration.class]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSourceInitializer': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'routingDataSource' defined in file [C:\workspace\routing-data-springboot\target\classes\com\zangland\routing\RoutingDataSource.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Property 'targetDataSources' is required