Hi, I have been using hibernate multitenency features with Hibernate 5 by specifying the following hibernate properties: <property name="hibernate.multiTenancy" value="DATABASE" /> <property name="hibernate.connection.datasource" value="java:jboss/datasources" /> <property name="hibernate.multi_tenant.datasource.identifier_for_any" value="myDefaultDatasource" /> <property name="hibernate.tenant_identifier_resolver" value="MyTenantIdentifierResolverImpl" /> Moving to Hibernate 6 this no longer worked instead an exception is thrown: Caused by: java.lang.ClassCastException: class org.jboss.as.naming.NamingContext cannot be cast to class javax.sql.DataSource (org.jboss.as.naming.NamingContext is in unnamed module of loader 'org.jboss.as.naming@27.0.0.Beta1' @3e7df9b1; javax.sql.DataSource is in module java.sql of loader 'platform') Adding the following property makes it work with Hibernate 6: <property name="hibernate.multi_tenant_connection_provider" value="org.hibernate.engine.jdbc.connections.spi.DataSourceBasedMultiTenantConnectionProviderImpl" /> But should the user have to do that? Looking in the user guide its says that:
The MultiTenantConnectionProvider to use can be specified in a number of ways:
- Use the hibernate.multi_tenant_connection_provider setting. It could name a MultiTenantConnectionProvider instance, a MultiTenantConnectionProvider implementation class reference or a MultiTenantConnectionProvider implementation class name.
- Passed directly to the org.hibernate.boot.registry.StandardServiceRegistryBuilder.
- If none of the above options match, but the settings do specify a hibernate.connection.datasource value, Hibernate will assume it should use the specific DataSourceBasedMultiTenantConnectionProviderImpl implementation which works on a number of pretty reasonable assumptions when running inside of an app server and using one javax.sql.DataSource per tenant. See its Javadocs for more details.
Number three looks like my case, but it doesn’t work. Looking at the code i can see that JdbcEnvironmentInitiator assumes only multitenency if hibernate.multi_tenant_connection_provider is set:
private JdbcConnectionAccess buildJdbcConnectionAccess(Map<?,?> configValues, ServiceRegistryImplementor registry) {
if ( !configValues.containsKey( AvailableSettings.MULTI_TENANT_CONNECTION_PROVIDER ) ) {
ConnectionProvider connectionProvider = registry.getService( ConnectionProvider.class );
return new ConnectionProviderJdbcConnectionAccess( connectionProvider );
}
else {
final MultiTenantConnectionProvider multiTenantConnectionProvider = registry.getService( MultiTenantConnectionProvider.class );
return new MultiTenantConnectionProviderJdbcConnectionAccess( multiTenantConnectionProvider );
}
}
MultiTenantConnectionProviderInitiator has a case for dealing with this part but I can’t see that it ever will be reached:
if ( !configurationValues.containsKey( AvailableSettings.MULTI_TENANT_CONNECTION_PROVIDER ) ) {
return null;
}
final Object configValue = configurationValues.get( AvailableSettings.MULTI_TENANT_CONNECTION_PROVIDER );
if ( configValue == null ) {
final Object dataSourceConfigValue = configurationValues.get( AvailableSettings.DATASOURCE );
if ( dataSourceConfigValue instanceof String ) {
return new DataSourceBasedMultiTenantConnectionProviderImpl();
}
return null;
}
|