开发者

How to configure multiple DataSources for multitenancy in Hibernate

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 data sources via spring perhaps by using properties files and get the data sources from the spring context based on tenant id.

More importantly, though I want to be able to configure my custom connection provider implementation that supports this开发者_开发知识库 multitenancy feature to be used by Hibernate instead of the injected ConnectionProvider that it uses by default.

How can i achieve this.


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


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


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 ConnectionProvider(s) 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
);


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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜