Таблицы, которые не создаются в нескольких базах данных в приложении загрузки spring
Я работаю над приложением spring для загрузки нескольких приложений. Я настроил несколько источников данных, как показано ниже:
application.properties
spring.multitenancy.datasource1.url=jdbc:mysql://localhost:3306/db1
spring.multitenancy.datasource1.username=root
spring.multitenancy.datasource1.password=****
spring.multitenancy.datasource1.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
spring.multitenancy.datasource2.url=jdbc:mysql://localhost:3306/db2
spring.multitenancy.datasource2.username=root
spring.multitenancy.datasource2.password=****
spring.multitenancy.datasource2.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
spring.multitenancy.datasource3.url=jdbc:mysql://localhost:3306/db3
spring.multitenancy.datasource3.username=root
spring.multitenancy.datasource3.password=****
spring.multitenancy.datasource3.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
DataSourceBasedMultiTenantConnectionProviderImpl.java
@Component
public class DataSourceBasedMultiTenantConnectionProviderImpl extends AbstractDataSourceBasedMultiTenantConnectionProviderImpl {
private static final long serialVersionUID = 8168907057647334460L;
private static final String DEFAULT_TENANT_ID = "tenant_1";
@Autowired
private DataSource dataSource1;
@Autowired
private DataSource dataSource2;
@Autowired
private DataSource dataSource3;
private Map<String, DataSource> map;
@PostConstruct
public void load() {
map = new HashMap<>();
map.put("tenant_1", dataSource1);
map.put("tenant_2", dataSource2);
map.put("tenant_3", dataSource3);
}
@Override
protected DataSource selectAnyDataSource() {
return map.get(DEFAULT_TENANT_ID);
}
@Override
protected DataSource selectDataSource(String tenantIdentifier) {
return map.get(tenantIdentifier);
}
}
MultitenancyProperties.java
@ConfigurationProperties("spring.multitenancy")
public class MultitenancyProperties {
@NestedConfigurationProperty
private DataSourceProperties datasource1;
@NestedConfigurationProperty
private DataSourceProperties datasource2;
@NestedConfigurationProperty
private DataSourceProperties datasource3;
public DataSourceProperties getDatasource1() {
return datasource1;
}
public void setDatasource1(DataSourceProperties datasource1) {
this.datasource1 = datasource1;
}
public DataSourceProperties getDatasource2() {
return datasource2;
}
public void setDatasource2(DataSourceProperties datasource2) {
this.datasource2 = datasource2;
}
public DataSourceProperties getDatasource3() {
return datasource3;
}
public void setDatasource3(DataSourceProperties datasource3) {
this.datasource3 = datasource3;
}
}
MultiTenancyJpaConfiguration.java
@Configuration
@EnableConfigurationProperties(JpaProperties.class)
public class MultiTenancyJpaConfiguration {
@Autowired
private DataSource dataSource;
@Autowired
private JpaProperties jpaProperties;
@Autowired
private MultiTenantConnectionProvider multiTenantConnectionProvider;
@Autowired
private CurrentTenantIdentifierResolver currentTenantIdentifierResolver;
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder) {
Map<String, Object> hibernateProps = new LinkedHashMap<>();
hibernateProps.putAll(jpaProperties.getHibernateProperties(dataSource));
hibernateProps.put(Environment.MULTI_TENANT, MultiTenancyStrategy.DATABASE);
hibernateProps.put(Environment.MULTI_TENANT_CONNECTION_PROVIDER, multiTenantConnectionProvider);
hibernateProps.put(Environment.MULTI_TENANT_IDENTIFIER_RESOLVER, currentTenantIdentifierResolver);
hibernateProps.put(Environment.DIALECT, "org.hibernate.dialect.MySQLDialect");
return builder.dataSource(dataSource).packages(HotelEntity.class.getPackage().getName()).properties(hibernateProps).jta(false).build();
}
}
Запуск приложений
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableConfigurationProperties(MultitenancyProperties.class)
public class Application {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
}
}
Когда я запускаю загрузочное приложение, все таблицы создаются только в первом источнике данных.
1) Как создать таблицы во всех источниках данных при запуске приложений?
2) Как увидеть соединения, открытые/закрытые для каждого из источников данных?
3) Есть ли лучший способ настройки приложения с несколькими арендаторами с помощью загрузки spring для повышения производительности?
Ответы
Ответ 1
Как сказал @Alex, вам нужны разные EntityManager, TransactionManager и Datasources. Вот как я это сделаю.
@Configuration
@EnableJpaRepositories(
entityManagerFactoryRef = "dataSource1EntityManagerFactory",
transactionManagerRef = "dataSource1TransactionManager",
basePackageClasses = dataSource1Repository.class)
public class DataSource1Config extends SqlConfig{// Put all common code in base class SqlConfig. If not remove it
@Bean
@Primary
public DataSource dataSource1() {
//create dataSource using MultitenancyProperties::getDataSource1
}
@Primary
@Bean(name = "dataSource1TransactionManager")
PlatformTransactionManager dataSource1TransactionManager(EntityManagerFactory dataSource1EntityManagerFactory) {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(dataSource1EntityManagerFactory);
return txManager;
}
@Primary
@Bean(name = "dataSource1EntityManagerFactory")
LocalContainerEntityManagerFactoryBean dataSource1EntityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource1());
em.setPackagesToScan(dataSource1Repository.class.getPackage().getName(), dataSource1ModelClass.class.getPackage().getName());
em.setPersistenceUnitName("dataSource1Db");
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(false);
em.setJpaVendorAdapter(vendorAdapter);
return em;
}
}
Вы можете создать два других класса. Не забудьте использовать @Primary
только один экземпляр источника данных, operatormanger и entitymanager (неважно, какой из них). Еще одно слово предостережения, убедитесь, что классы репозитория находятся в разных пакетах для всех трех баз данных.
Ответ 2
Вам нужны 2 разных фабрики персистентности, а не один, каждый должен создавать разные EntityManager для разных источников данных. Также должно быть отмечено, что каждое сопоставление объектов должно использоваться только с одним менеджером сущностей.
Посмотреть полное решение здесь:
http://www.baeldung.com/spring-data-jpa-multiple-databases
Ответ 3
Попробуйте добавить следующие свойства:
spring.jpa.generate-ddl=true