-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Closed as not planned
Closed as not planned
Copy link
Labels
status: declinedA suggestion or change that we don't feel we should currently applyA suggestion or change that we don't feel we should currently apply
Description
Hi,
I created a multi-tenancy application with Spring Boot and JPA.
When TenantIdentifier is not returning any default tenant value then my application is failing with the below error.
` TenantContext.java
public class TenantContext {
private static final InheritableThreadLocal<String> CURRENT_TENANT = new InheritableThreadLocal();
private static final Logger LOGGER = LoggerFactory.getLogger(TenantContext.class);
public TenantContext() {
}
public static String getCurrentTenant() {
return (String)CURRENT_TENANT.get();
}
public static void setCurrentTenant(String tenant) {
CURRENT_TENANT.set(tenant);
LOGGER.debug("Setting current tenant in tenant context to:{}", tenant);
}
}
`
`
TenantIdentifier.java
@Component
public class TenantIdentifier implements CurrentTenantIdentifierResolver {
private static final Logger logger = LoggerFactory.getLogger(TenantIdentifier.class);
@Override
public String resolveCurrentTenantIdentifier() {
logger.info("resolveCurrentTenantIdentifier called");
String tenant = TenantContext.getCurrentTenant();
logger.info("resolveCurrentTenantIdentifier called tenant {}", tenant);
return tenant;
}
@Override
public boolean validateExistingCurrentSessions() {
return true;
}
}
`
`PersistenceJpaConfigWithMultitenancy.java
@Configuration
@EnableJpaRepositories(basePackages = {"*****.**.persistence.repository"}, repositoryFactoryBeanClass =
ConfigurationRepositoryFactory.class)
@EnableTransactionManagement
public class PersistenceJpaConfigWithMultitenancy {
private static final Logger logger = LoggerFactory.getLogger(PersistenceJpaConfigWithMultitenancy.class);
@Autowired
HikariDataSourceBuilder hikariDataSourceBuilder;
@Autowired
private EnvironmentService environmentService;
@Bean
public MultiTenantConnectionProvider multiTenantConnectionProvider() {
logger.info("Called DataSourceBasedMultiTenantConnectionProviderImpl");
return new DataSourceBasedMultiTenantConnectionProviderImpl();
}
@Bean
public CurrentTenantIdentifierResolver currentTenantIdentifierResolver() {
logger.info("called TenantIdentifier");
return new TenantIdentifier();
}
private LocalContainerEntityManagerFactoryBean getLocalContainerEntityManagerFactoryBean() {
return new LocalContainerEntityManagerFactoryBean();
}
@Bean(name = "entityManagerFactory")
@Primary
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() {
logger.info("Setting the entityManagerFactory bean"); //TODO: to be removed later
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
Map<String, Object> hibernateProps = new LinkedHashMap<>();
hibernateProps.put(Environment.MULTI_TENANT, MultiTenancyStrategy.DATABASE);
hibernateProps.put(Environment.MULTI_TENANT_CONNECTION_PROVIDER,
DataSourceBasedMultiTenantConnectionProviderImpl.class);
hibernateProps.put(Environment.MULTI_TENANT_IDENTIFIER_RESOLVER, TenantIdentifier.class);
LocalContainerEntityManagerFactoryBean em = getLocalContainerEntityManagerFactoryBean();
em.setPackagesToScan("com.swgrp.itomdi.administration.persistence.model");
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());
em.setJpaPropertyMap(hibernateProps);
return em;
}
@Bean
@ConditionalOnProperty(
name = "config.store.type",
havingValue = "db")
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager transactionManager
= new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
return transactionManager;
}
@Bean
public EntityManagerFactory entityManagerFactory(LocalContainerEntityManagerFactoryBean entityManagerFactoryBean) {
return entityManagerFactoryBean.getObject();
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
Properties additionalProperties() {
Properties properties = new Properties();
properties.setProperty("spring.jpa.database", "Vertica");
properties.setProperty("hibernate.show_sql", "true");
properties.setProperty(
"hibernate.dialect", "org.hibernate.dialect.VerticaDialect");
properties.setProperty("spring.data.jpa.repositories.enabled", "true");
properties.setProperty("hibernate.temp.use_jdbc_metadata_defaults", "false");
return properties;
}
}
`
` DataSourceBasedMultiTenantConnectionProviderImpl.java
@Component
public class DataSourceBasedMultiTenantConnectionProviderImpl extends
AbstractDataSourceBasedMultiTenantConnectionProviderImpl {
private static Logger logger = LoggerFactory.getLogger(DataSourceBasedMultiTenantConnectionProviderImpl.class);
@Autowired
private HikariDataSourceBuilder hikariDataSourceBuilder;
@Autowired
private EnvironmentService environmentService;
@Override
protected DataSource selectAnyDataSource() {
logger.info("Calling selectAnyDataSource");
return AdministrationCacheProvider.getAdminCache().values().iterator().next().getTenantDataSource(); //TODO: check if this can be removed and send null instead
}
@Override
protected DataSource selectDataSource(String tenant) {
logger.info("Returning datasource for tenant:{}", tenant);
return AdministrationCacheProvider.getAdminCache().get(tenant).getTenantDataSource();
}
}
`
Metadata
Metadata
Assignees
Labels
status: declinedA suggestion or change that we don't feel we should currently applyA suggestion or change that we don't feel we should currently apply