22
22
import org .hibernate .service .spi .ServiceRegistryImplementor ;
23
23
import org .hibernate .service .spi .Stoppable ;
24
24
25
+ import static org .hibernate .cfg .JdbcSettings .DATASOURCE ;
25
26
import static org .hibernate .cfg .MultiTenancySettings .TENANT_IDENTIFIER_TO_USE_FOR_ANY_KEY ;
26
27
27
28
/**
28
- * A concrete implementation of the {@link MultiTenantConnectionProvider} contract bases on a number of
29
- * reasonable assumptions. We assume that:<ul>
29
+ * A concrete implementation of the {@link MultiTenantConnectionProvider} contract bases on
30
+ * a number of reasonable assumptions. We assume that:<ul>
30
31
* <li>
31
- * The {@link DataSource} instances are all available from JNDI named by the tenant identifier relative
32
- * to a single base JNDI context
32
+ * The {@link DataSource} instances are all available from JNDI named by the tenant
33
+ * identifier relative to a single base JNDI context.
33
34
* </li>
34
35
* <li>
35
36
* {@value AvailableSettings#DATASOURCE} is a string naming either the {@literal any}
36
- * data source or the base JNDI context. If the latter, {@link MultiTenancySettings#TENANT_IDENTIFIER_TO_USE_FOR_ANY_KEY} must
37
- * also be set.
37
+ * data source or the base JNDI context. If the latter,
38
+ * {@link MultiTenancySettings#TENANT_IDENTIFIER_TO_USE_FOR_ANY_KEY} must also be set.
38
39
* </li>
39
40
* </ul>
40
41
*
@@ -44,10 +45,11 @@ public class DataSourceBasedMultiTenantConnectionProviderImpl<T>
44
45
extends AbstractDataSourceBasedMultiTenantConnectionProviderImpl <T >
45
46
implements ServiceRegistryAwareService , Stoppable {
46
47
47
- private Map <T , DataSource > dataSourceMap ;
48
+ private final Map <T , DataSource > dataSourceMap = new ConcurrentHashMap <>() ;
48
49
private JndiService jndiService ;
49
50
private T tenantIdentifierForAny ;
50
51
private String baseJndiNamespace ;
52
+ private String jndiName ;
51
53
52
54
@ Override
53
55
protected DataSource selectAnyDataSource () {
@@ -65,21 +67,17 @@ protected DataSource selectDataSource(T tenantIdentifier) {
65
67
}
66
68
67
69
private Map <T , DataSource > dataSourceMap () {
68
- if ( dataSourceMap == null ) {
69
- dataSourceMap = new ConcurrentHashMap <>();
70
- }
71
70
return dataSourceMap ;
72
71
}
73
72
74
73
@ Override
75
74
public void injectServices (ServiceRegistryImplementor serviceRegistry ) {
76
- final Object dataSourceConfigValue =
77
- serviceRegistry .requireService ( ConfigurationService .class )
78
- .getSettings ().get ( AvailableSettings .DATASOURCE );
75
+ final ConfigurationService configurationService = serviceRegistry .requireService ( ConfigurationService .class );
76
+ final Object dataSourceConfigValue = configurationService .getSettings ().get ( DATASOURCE );
79
77
if ( !(dataSourceConfigValue instanceof String ) ) {
80
- throw new HibernateException ( "Improper set up of DataSourceBasedMultiTenantConnectionProviderImpl " );
78
+ throw new HibernateException ( "illegal value for configuration setting '" + DATASOURCE + "' " );
81
79
}
82
- final String jndiName = (String ) dataSourceConfigValue ;
80
+ jndiName = (String ) dataSourceConfigValue ;
83
81
84
82
jndiService = serviceRegistry .getService ( JndiService .class );
85
83
if ( jndiService == null ) {
@@ -91,17 +89,18 @@ public void injectServices(ServiceRegistryImplementor serviceRegistry) {
91
89
throw new HibernateException ( "JNDI name [" + jndiName + "] could not be resolved" );
92
90
}
93
91
94
- if ( namedObject instanceof DataSource ) {
92
+ if ( namedObject instanceof DataSource datasource ) {
95
93
final int loc = jndiName .lastIndexOf ( '/' );
96
- this .baseJndiNamespace = jndiName .substring ( 0 , loc );
97
- this .tenantIdentifierForAny = (T ) jndiName .substring ( loc + 1 );
98
- dataSourceMap ().put ( tenantIdentifierForAny , (DataSource ) namedObject );
94
+ baseJndiNamespace = jndiName .substring ( 0 , loc );
95
+ final String prefix = jndiName .substring (loc + 1 );
96
+ tenantIdentifierForAny = (T ) prefix ;
97
+ dataSourceMap ().put ( tenantIdentifierForAny , datasource );
99
98
}
100
99
else if ( namedObject instanceof Context ) {
101
- this . baseJndiNamespace = jndiName ;
102
- this . tenantIdentifierForAny = ( T ) serviceRegistry . requireService ( ConfigurationService . class )
103
- .getSettings ()
104
- . get ( TENANT_IDENTIFIER_TO_USE_FOR_ANY_KEY ) ;
100
+ baseJndiNamespace = jndiName ;
101
+ final Object configuredTenantId =
102
+ configurationService .getSettings (). get ( TENANT_IDENTIFIER_TO_USE_FOR_ANY_KEY );
103
+ tenantIdentifierForAny = ( T ) configuredTenantId ;
105
104
if ( tenantIdentifierForAny == null ) {
106
105
throw new HibernateException ( "JNDI name named a Context, but tenant identifier to use for ANY was not specified" );
107
106
}
@@ -116,10 +115,7 @@ else if ( namedObject instanceof Context ) {
116
115
117
116
@ Override
118
117
public void stop () {
119
- if ( dataSourceMap != null ) {
120
- dataSourceMap .clear ();
121
- dataSourceMap = null ;
122
- }
118
+ dataSourceMap .clear ();
123
119
}
124
120
125
121
@ Override
@@ -139,5 +135,4 @@ public String toInfoString() {
139
135
}
140
136
};
141
137
}
142
-
143
138
}
0 commit comments