Staffan Hörke (
https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%...
) *created* an issue
Hibernate ORM (
https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiOWFiNmQzYjQw...
) / Improvement (
https://hibernate.atlassian.net/browse/HHH-15621?atlOrigin=eyJpIjoiOWFiNm...
) HHH-15621 (
https://hibernate.atlassian.net/browse/HHH-15621?atlOrigin=eyJpIjoiOWFiNm...
) Clearify configuration of datasource based multitenancy (
https://hibernate.atlassian.net/browse/HHH-15621?atlOrigin=eyJpIjoiOWFiNm...
)
Issue Type: Improvement Affects Versions: 6.1.4 Assignee: Unassigned Components:
hibernate-core Created: 21/Oct/2022 09:08 AM Environment: Wildfly 27.0.0.Beta1 Priority:
Minor Reporter: Staffan Hörke (
https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%...
)
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(a)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 (
https://docs.jboss.org/hibernate/orm/6.1/javadocs/org/hibernate/engine/jd...
) 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
) ) {
// nothing to do , but given the separate hierarchies have to handle this here.
return null ;
}
final Object configValue = configurationValues.get(
AvailableSettings.MULTI_TENANT_CONNECTION_PROVIDER );
if ( configValue == null ) {
// if they also specified the data source *name*, then lets assume they want
// DataSourceBasedMultiTenantConnectionProviderImpl
final Object dataSourceConfigValue = configurationValues.get(
AvailableSettings.DATASOURCE );
if ( dataSourceConfigValue instanceof String ) {
return new DataSourceBasedMultiTenantConnectionProviderImpl();
}
return null ;
}
(
https://hibernate.atlassian.net/browse/HHH-15621#add-comment?atlOrigin=ey...
) Add Comment (
https://hibernate.atlassian.net/browse/HHH-15621#add-comment?atlOrigin=ey...
)
Get Jira notifications on your phone! Download the Jira Cloud app for Android (
https://play.google.com/store/apps/details?id=com.atlassian.android.jira....
) or iOS (
https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=Em...
) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100209- sha1:392b984 )