12
12
13
13
import java .lang .invoke .MethodHandles ;
14
14
import java .lang .reflect .Field ;
15
+ import java .util .Map ;
15
16
import java .util .stream .Stream ;
16
17
17
18
import org .hibernate .HibernateException ;
19
+ import org .hibernate .boot .registry .StandardServiceInitiator ;
18
20
import org .hibernate .boot .registry .StandardServiceRegistry ;
19
21
import org .hibernate .boot .registry .StandardServiceRegistryBuilder ;
20
22
import org .hibernate .cfg .AvailableSettings ;
33
35
import org .hibernate .dialect .SQLServerDialect ;
34
36
import org .hibernate .dialect .SpannerDialect ;
35
37
import org .hibernate .dialect .SybaseDialect ;
38
+ import org .hibernate .engine .jdbc .dialect .internal .DialectFactoryImpl ;
39
+ import org .hibernate .engine .jdbc .dialect .spi .DialectFactory ;
40
+ import org .hibernate .engine .jdbc .dialect .spi .DialectResolutionInfo ;
41
+ import org .hibernate .engine .jdbc .dialect .spi .DialectResolutionInfoSource ;
36
42
import org .hibernate .engine .jdbc .env .spi .JdbcEnvironment ;
37
43
import org .hibernate .internal .CoreMessageLogger ;
38
44
import org .hibernate .service .spi .ServiceException ;
45
+ import org .hibernate .service .spi .ServiceRegistryImplementor ;
39
46
40
47
import org .hibernate .testing .env .TestingDatabaseInfo ;
41
48
import org .hibernate .testing .logger .Triggerable ;
49
+ import org .hibernate .testing .orm .junit .DialectContext ;
42
50
import org .hibernate .testing .orm .junit .Jira ;
43
51
import org .hibernate .testing .orm .logger .LoggerInspectionExtension ;
44
52
import org .junit .jupiter .api .BeforeEach ;
@@ -89,8 +97,7 @@ void testAccessAllowed() {
89
97
.doesNotContainKeys ( JdbcSettings .DIALECT , JdbcSettings .JAKARTA_HBM2DDL_DB_NAME );
90
98
91
99
try (StandardServiceRegistry registry = registryBuilder .build ()) {
92
- final JdbcEnvironment jdbcEnvironment = registry .getService ( JdbcEnvironment .class );
93
- final Dialect dialect = jdbcEnvironment .getDialect ();
100
+ final Dialect dialect = getDialect ( registry );
94
101
assertThat ( dialect ).isNotNull ();
95
102
assertThat ( dialect ).isInstanceOf ( H2Dialect .class );
96
103
}
@@ -134,7 +141,20 @@ static Stream<Arguments> dialects() {
134
141
135
142
@ ParameterizedTest
136
143
@ MethodSource ("dialects" )
137
- void testAccessDisabledExplicitDialect (String productName , Class <?> dialectClass , DatabaseVersion expectedDatabaseVersion ) {
144
+ void testAccessDisabledExplicitDialect (String productName , Class <?> dialectClass ,
145
+ DatabaseVersion expectedDatabaseVersion ) {
146
+ try ( StandardServiceRegistry registry = createRegistryWithMetadataAccessDisabledAndDialect ( dialectClass ) ) {
147
+ final Dialect dialect = getDialect ( registry );
148
+ assertThat ( dialect ).isInstanceOf ( dialectClass );
149
+ assertThat ( dialect .getVersion () ).isEqualTo ( expectedDatabaseVersion );
150
+ }
151
+
152
+ assertThat ( triggerable .triggerMessages () )
153
+ .as ( triggerable .toString () )
154
+ .isEmpty ();
155
+ }
156
+
157
+ private StandardServiceRegistry createRegistryWithMetadataAccessDisabledAndDialect (Class <?> dialectClass ) {
138
158
final StandardServiceRegistryBuilder registryBuilder = new StandardServiceRegistryBuilder ();
139
159
registryBuilder .clearSettings ();
140
160
@@ -143,16 +163,7 @@ void testAccessDisabledExplicitDialect(String productName, Class<?> dialectClass
143
163
assertThat ( registryBuilder .getSettings () )
144
164
.doesNotContainKeys ( JdbcSettings .JAKARTA_HBM2DDL_DB_NAME );
145
165
146
- try (StandardServiceRegistry registry = registryBuilder .build ()) {
147
- final JdbcEnvironment jdbcEnvironment = registry .getService ( JdbcEnvironment .class );
148
- final Dialect dialect = jdbcEnvironment .getDialect ();
149
- assertThat ( dialect ).isInstanceOf ( dialectClass );
150
- assertThat ( dialect .getVersion () ).isEqualTo ( expectedDatabaseVersion );
151
- }
152
-
153
- assertThat ( triggerable .triggerMessages () )
154
- .as ( triggerable .toString () )
155
- .isEmpty ();
166
+ return registryBuilder .build ();
156
167
}
157
168
158
169
@ ParameterizedTest
@@ -190,8 +201,7 @@ void testAccessDisabledNoDialectNorProductName() {
190
201
191
202
registryBuilder .applySetting ( JdbcSettings .ALLOW_METADATA_ON_BOOT , false );
192
203
try (StandardServiceRegistry registry = registryBuilder .build ()) {
193
- final JdbcEnvironment jdbcEnvironment = registry .getService ( JdbcEnvironment .class );
194
- final Dialect dialect = jdbcEnvironment .getDialect ();
204
+ final Dialect dialect = getDialect ( registry );
195
205
fail ( "Should fail to boot - " + dialect );
196
206
}
197
207
catch (ServiceException expected ) {
@@ -201,6 +211,50 @@ void testAccessDisabledNoDialectNorProductName() {
201
211
}
202
212
}
203
213
214
+ @ Test
215
+ void testDetermineDatabaseVersion () {
216
+ final Dialect metadataAccessDisabledDialect ;
217
+ try ( StandardServiceRegistry registry =
218
+ createRegistryWithMetadataAccessDisabledAndDialect ( DialectContext .getDialectClass () ) ) {
219
+ // The version on this dialect may be anything, but most likely will be the minimum version.
220
+ // We're not interested in that, but in how determineDatabaseVersion() behaves for this dialect,
221
+ // when passed actual resolution info -- which Quarkus may do.
222
+ metadataAccessDisabledDialect = getDialect ( registry );
223
+ }
224
+
225
+ try ( StandardServiceRegistry registry = createRegistryWithTestedDatabaseAndMetadataAccessAllowed () ) {
226
+ final Dialect metadataAccessAllowedDialect = getDialect ( registry );
227
+
228
+ // We expect determineDatabaseVersion(), when called on metadataAccessDisabledDialect,
229
+ // to return the version that would have been returned,
230
+ // had we booted up with auto-detection of version (metadata access allowed).
231
+ assertThat ( metadataAccessDisabledDialect .determineDatabaseVersion ( getDialectResolutionInfo ( registry ) ) )
232
+ .isEqualTo ( metadataAccessAllowedDialect .getVersion () );
233
+ }
234
+ }
235
+
236
+ private StandardServiceRegistry createRegistryWithTestedDatabaseAndMetadataAccessAllowed () {
237
+ final StandardServiceRegistryBuilder registryBuilder = new StandardServiceRegistryBuilder ();
238
+
239
+ registryBuilder .addInitiator ( new CapturingDialectFactory .Initiator () );
240
+
241
+ // allow access to the jdbc metadata
242
+ registryBuilder .applySetting ( JdbcSettings .ALLOW_METADATA_ON_BOOT , true );
243
+
244
+ // leave connection info as defined in global test configuration (most likely system properties)
245
+
246
+ return registryBuilder .build ();
247
+ }
248
+
249
+ private static Dialect getDialect (StandardServiceRegistry registry ) {
250
+ return registry .getService ( JdbcEnvironment .class ).getDialect ();
251
+ }
252
+
253
+ private static DialectResolutionInfo getDialectResolutionInfo (StandardServiceRegistry registry ) {
254
+ return ( (CapturingDialectFactory ) registry .getService ( DialectFactory .class ) )
255
+ .capturedDialectResolutionInfoSource .getDialectResolutionInfo ();
256
+ }
257
+
204
258
// Ugly hack because neither MINIMUM_VERSION nor getMinimumSupportedVersion()
205
259
// can be accessed from this test.
206
260
private static DatabaseVersion getVersionConstant (Class <? extends Dialect > dialectClass , String versionConstantName ) {
@@ -213,4 +267,29 @@ private static DatabaseVersion getVersionConstant(Class<? extends Dialect> diale
213
267
throw new RuntimeException ( "Error extracting '" + versionConstantName + "' from '" + dialectClass + "'" , e );
214
268
}
215
269
}
270
+
271
+ // A hack to easily retrieve DialectResolutionInfo exactly as it would be constructed by Hibernate ORM
272
+ private static class CapturingDialectFactory extends DialectFactoryImpl {
273
+ static class Initiator implements StandardServiceInitiator <DialectFactory > {
274
+ @ Override
275
+ public Class <DialectFactory > getServiceInitiated () {
276
+ return DialectFactory .class ;
277
+ }
278
+
279
+ @ Override
280
+ public DialectFactory initiateService (Map <String , Object > configurationValues ,
281
+ ServiceRegistryImplementor registry ) {
282
+ return new CapturingDialectFactory ();
283
+ }
284
+ }
285
+
286
+ DialectResolutionInfoSource capturedDialectResolutionInfoSource ;
287
+
288
+ @ Override
289
+ public Dialect buildDialect (Map <String , Object > configValues , DialectResolutionInfoSource resolutionInfoSource )
290
+ throws HibernateException {
291
+ this .capturedDialectResolutionInfoSource = resolutionInfoSource ;
292
+ return super .buildDialect ( configValues , resolutionInfoSource );
293
+ }
294
+ }
216
295
}
0 commit comments