How to configure multiple DataSources for multitenancy in Hibernate

前端 未结 4 1253
别那么骄傲
别那么骄傲 2020-12-28 11:16

I am trying to add multitenancy to a java application using the separate schema approach as outlined in this webinar

I wanted to know how would I configure multiple

相关标签:
4条回答
  • 2020-12-28 11:33

    If you want to do multi-tenancy by ConnectionProvider, you'll need a thread-local to provide context. See this brief run-through:

    http://literatejava.com/hibernate/multi-tenancy-architecture-with-hibernate/

    0 讨论(0)
  • 2020-12-28 11:37

    This post demonstrate how to use spring security and AbstractRoutingDataSource to build up Multi-Tenancy SaaS applications. Extend Spring Security to Protect Multi-tenant SaaS Applications

    0 讨论(0)
  • 2020-12-28 11:38

    Use the AbstractRoutingDataSource. See my answer located @ Multiple Entity Manager issue in Spring when using more than one datasource.

    0 讨论(0)
  • 2020-12-28 11:47

    As I explained in this article, the routing can be done by Hibernate via its MultiTenancyConnectionProvider which you can implement like this:

    public class MultiTenantConnectionProvider
            extends AbstractMultiTenantConnectionProvider {
    
        public static final MultiTenantConnectionProvider INSTANCE =
                new MultiTenantConnectionProvider();
    
        private final Map<String, ConnectionProvider> connectionProviderMap = 
                new HashMap<>();
    
        Map<String, ConnectionProvider> getConnectionProviderMap() {
            return connectionProviderMap;
        }
    
        @Override
        protected ConnectionProvider getAnyConnectionProvider() {
            return connectionProviderMap.get(
                TenantContext.DEFAULT_TENANT_IDENTIFIER
            );
        }
    
        @Override
        protected ConnectionProvider selectConnectionProvider(
                String tenantIdentifier) {
            return connectionProviderMap.get(
                tenantIdentifier
            );
        }
    }
    

    Assuming each tenant uses its own dedicated DataSource, you can register the individual ConnectionProviders using a utility method like this one:

    private void addTenantConnectionProvider(
            String tenantId, 
            DataSource tenantDataSource, 
            Properties properties) {
    
        DatasourceConnectionProviderImpl connectionProvider = 
            new DatasourceConnectionProviderImpl();
        connectionProvider.setDataSource(tenantDataSource);
        connectionProvider.configure(properties);
    
        MultiTenantConnectionProvider.INSTANCE
        .getConnectionProviderMap()
        .put(
            tenantId, 
            connectionProvider
        );
    }
    

    You can register a default tenant for admin-related tasks:

    addTenantConnectionProvider(
        TenantContext.DEFAULT_TENANT_IDENTIFIER, 
        defaultDataSource, 
        properties()
    );
    

    And for the actual tenants, you could use a method like this one:

    private void addTenantConnectionProvider(
            String tenantId) {
    
        DataSourceProvider dataSourceProvider = database()
        .dataSourceProvider();
    
        Properties properties = properties();
    
        MysqlDataSource tenantDataSource = new MysqlDataSource();
        tenantDataSource.setDatabaseName(tenantId);
        tenantDataSource.setUser(dataSourceProvider.username());
        tenantDataSource.setPassword(dataSourceProvider.password());
    
        properties.put(
            Environment.DATASOURCE,
            dataSourceProxyType().dataSource(tenantDataSource)
        );
    
        addTenantConnectionProvider(
            tenantId, 
            tenantDataSource, 
            properties
        );
    }
    

    You can change the MysqlDataSource to whatever database you are using.

    Then, registering the tenants is as simple as that:

    addTenantConnectionProvider("asia");
    addTenantConnectionProvider("europe");
    

    The last thing to take into consideration is to provide the MultiTenancyConnectionProvider implementation to Hibernate via the hibernate.multi_tenant_connection_provider configuration property.

    properties.put(
        AvailableSettings.MULTI_TENANT_CONNECTION_PROVIDER, 
        MultiTenantConnectionProvider.INSTANCE
    );
    
    0 讨论(0)
提交回复
热议问题