I know there are a lot of posts on spring boot multi-tenancy, but I have to post this since I just used the multi-tenancy connection in one of my projects.
I will keep it simple, basically, there are 3 parts to achieving the multi-tenancy connection.
EntityManager
DataSource
TransactionManager
We can have as many connections as required to multiple schemas or databases, each connection should have its own above-configuration objects, In the below example, we are trying to fetch the list of Product from schema1 and list of User from schema 2application.properties
spring.datasource.jdbcUrl=jdbc:mysql://127.0.0.1:3306/schema_1
spring.datasource.username=username
spring.datasource.password=password
spring.second-datasource.jdbcUrl=jdbc:mysql://127.0.0.1:3306/schema_2
spring.second-datasource.username=username
spring.second-datasource.password=password
Configuration class for schema1
@Configuration
@PropertySource({"classpath:application.properties"})
@EnableJpaRepositories(basePackages = "dev.vinodkmr.dao.product", entityManagerFactoryRef = "productEntityManager", transactionManagerRef = "productTransactionManager")
public class PersistenceProductAutoConfiguration {
@Autowired
private Environment env;
public PersistenceProductAutoConfiguration() {
super();
}
//Entity Manager
@Bean
public LocalContainerEntityManagerFactoryBean productEntityManager() {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(productDataSource());
em.setPackagesToScan("dev.vinodkmr.model.product");
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
final HashMap properties = new HashMap();
properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
properties.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
em.setJpaPropertyMap(properties);
return em;
}
//DataSource
@Bean
@ConfigurationProperties(prefix="spring.datasource")
public DataSource productDataSource() {
return DataSourceBuilder.create().build();
}
//Transaction Manager
@Bean
public PlatformTransactionManager productTransactionManager() {
final JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(productEntityManager().getObject());
return transactionManager;
}
}
Configuration class for schema2
@Configuration
@PropertySource({"classpath:application.properties"})
@EnableJpaRepositories(basePackages = "dev.vinodkmr.dao.user", entityManagerFactoryRef = "userEntityManager", transactionManagerRef = "userTransactionManager")
public class PersistenceUserAutoConfiguration {
@Autowired
private Environment env;
public PersistenceUserAutoConfiguration() {
super();
}
@Primary
@Bean
public LocalContainerEntityManagerFactoryBean userEntityManager() {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(userDataSource());
em.setPackagesToScan("dev.vinodkmr.model.user");
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
final HashMap properties = new HashMap();
properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
properties.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
em.setJpaPropertyMap(properties);
return em;
}
@Bean
@Primary
@ConfigurationProperties(prefix="spring.second-datasource")
public DataSource userDataSource() {
return DataSourceBuilder.create().build();
}
@Primary
@Bean
public PlatformTransactionManager userTransactionManager() {
final JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(userEntityManager().getObject());
return transactionManager;
}
}
We need to have the entities User and Product and respective repositories in a separate package as configured in the above configuration classes which are straightforward.Please post your doubts in the comment section, if any.
0 comments:
Post a Comment