Skip to content

Commit 513f4e5

Browse files
committed
HHH-19063 - Drop forms of SchemaNameResolver performing reflection
# Conflicts: # hibernate-core/src/main/java/org/hibernate/dialect/SybaseDialect.java
1 parent 995b673 commit 513f4e5

File tree

7 files changed

+90
-26
lines changed

7 files changed

+90
-26
lines changed

hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3668,12 +3668,7 @@ public String getCurrentSchemaCommand() {
36683668
* {@link Connection}, usually {@link DefaultSchemaNameResolver}.
36693669
*
36703670
* @return The schema name resolver strategy
3671-
*
3672-
* @deprecated Since Hibernate now baselines on Java 17,
3673-
* {@link Connection#getSchema()} is always available directly.
3674-
* Never used internally.
36753671
*/
3676-
@Deprecated
36773672
public SchemaNameResolver getSchemaNameResolver() {
36783673
return DefaultSchemaNameResolver.INSTANCE;
36793674
}

hibernate-core/src/main/java/org/hibernate/dialect/SybaseDialect.java

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,8 @@
44
*/
55
package org.hibernate.dialect;
66

7-
import java.sql.DatabaseMetaData;
8-
import java.sql.SQLException;
9-
import java.sql.Types;
10-
import java.time.temporal.TemporalAccessor;
11-
import java.util.Calendar;
12-
import java.util.Date;
13-
import java.util.TimeZone;
14-
7+
import jakarta.persistence.TemporalType;
8+
import org.hibernate.HibernateException;
159
import org.hibernate.boot.model.FunctionContributions;
1610
import org.hibernate.boot.model.TypeContributions;
1711
import org.hibernate.dialect.function.CommonFunctionFactory;
@@ -24,20 +18,22 @@
2418
import org.hibernate.dialect.unique.SkipNullableUniqueDelegate;
2519
import org.hibernate.dialect.unique.UniqueDelegate;
2620
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
21+
import org.hibernate.engine.jdbc.env.internal.DefaultSchemaNameResolver;
2722
import org.hibernate.engine.jdbc.env.spi.IdentifierCaseStrategy;
2823
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
2924
import org.hibernate.engine.jdbc.env.spi.IdentifierHelperBuilder;
3025
import org.hibernate.engine.jdbc.env.spi.NameQualifierSupport;
26+
import org.hibernate.engine.jdbc.env.spi.SchemaNameResolver;
3127
import org.hibernate.engine.spi.LoadQueryInfluencers;
3228
import org.hibernate.engine.spi.SessionFactoryImplementor;
3329
import org.hibernate.procedure.internal.JTDSCallableStatementSupport;
3430
import org.hibernate.procedure.internal.SybaseCallableStatementSupport;
3531
import org.hibernate.procedure.spi.CallableStatementSupport;
32+
import org.hibernate.query.common.TemporalUnit;
3633
import org.hibernate.query.spi.QueryOptions;
3734
import org.hibernate.query.spi.QueryParameterBindings;
3835
import org.hibernate.query.sqm.CastType;
3936
import org.hibernate.query.sqm.IntervalType;
40-
import org.hibernate.query.common.TemporalUnit;
4137
import org.hibernate.query.sqm.internal.DomainParameterXref;
4238
import org.hibernate.query.sqm.sql.SqmTranslator;
4339
import org.hibernate.query.sqm.sql.SqmTranslatorFactory;
@@ -63,7 +59,15 @@
6359
import org.hibernate.type.descriptor.jdbc.TinyIntAsSmallIntJdbcType;
6460
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
6561

66-
import jakarta.persistence.TemporalType;
62+
import java.sql.Connection;
63+
import java.sql.DatabaseMetaData;
64+
import java.sql.ResultSet;
65+
import java.sql.SQLException;
66+
import java.sql.Types;
67+
import java.time.temporal.TemporalAccessor;
68+
import java.util.Calendar;
69+
import java.util.Date;
70+
import java.util.TimeZone;
6771

6872
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate;
6973
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsLocalTime;
@@ -91,6 +95,8 @@ public class SybaseDialect extends AbstractTransactSQLDialect {
9195
@Deprecated(forRemoval = true)
9296
protected final boolean jtdsDriver;
9397

98+
private final SchemaNameResolver schemaNameResolver;
99+
94100
public SybaseDialect() {
95101
this( MINIMUM_VERSION );
96102
}
@@ -99,12 +105,20 @@ public SybaseDialect(DatabaseVersion version) {
99105
super(version);
100106
this.driverKind = SybaseDriverKind.OTHER;
101107
this.jtdsDriver = true;
108+
this.schemaNameResolver = determineSchemaNameResolver( driverKind );
109+
}
110+
111+
private static SchemaNameResolver determineSchemaNameResolver(SybaseDriverKind driverKind) {
112+
return driverKind == SybaseDriverKind.JTDS
113+
? new JTDSSchemaNameResolver()
114+
: DefaultSchemaNameResolver.INSTANCE;
102115
}
103116

104117
public SybaseDialect(DialectResolutionInfo info) {
105118
super(info);
106119
this.driverKind = SybaseDriverKind.determineKind( info );
107120
this.jtdsDriver = driverKind == SybaseDriverKind.JTDS;
121+
this.schemaNameResolver = determineSchemaNameResolver( driverKind );
108122
}
109123

110124
@Override
@@ -321,6 +335,11 @@ public boolean canCreateSchema() {
321335
return false;
322336
}
323337

338+
@Override
339+
public SchemaNameResolver getSchemaNameResolver() {
340+
return schemaNameResolver;
341+
}
342+
324343
@Override
325344
public String getCurrentSchemaCommand() {
326345
return "select user_name()";
@@ -556,4 +575,26 @@ public boolean supportsRowValueConstructorSyntaxInInList() {
556575
return false;
557576
}
558577

578+
private static class JTDSSchemaNameResolver implements SchemaNameResolver {
579+
@Override
580+
public String resolveSchemaName(Connection connection, Dialect dialect) throws SQLException {
581+
//noinspection deprecation
582+
final String command = dialect.getCurrentSchemaCommand();
583+
if ( command == null ) {
584+
throw new HibernateException(
585+
"Use of DefaultSchemaNameResolver requires Dialect to provide the " +
586+
"proper SQL statement/command but provided Dialect [" +
587+
dialect.getClass().getName() + "] did not return anything " +
588+
"from Dialect#getCurrentSchemaCommand"
589+
);
590+
}
591+
592+
try (final java.sql.Statement statement = connection.createStatement()) {
593+
try (ResultSet resultSet = statement.executeQuery( command )) {
594+
return resultSet.next() ? resultSet.getString( 1 ) : null;
595+
}
596+
}
597+
}
598+
}
599+
559600
}

hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/DefaultSchemaNameResolver.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,11 @@
1111
import java.sql.SQLException;
1212

1313
/**
14-
* Default implementation of {@link SchemaNameResolver}.
15-
*
16-
* @deprecated Since Hibernate now baselines on Java 17,
17-
* {@link Connection#getSchema()} is always available directly.
14+
* Default implementation of {@link SchemaNameResolver}
15+
* using {@link Connection#getSchema()}.
1816
*
1917
* @author Steve Ebersole
2018
*/
21-
@Deprecated
2219
public class DefaultSchemaNameResolver implements SchemaNameResolver {
2320
public static final DefaultSchemaNameResolver INSTANCE = new DefaultSchemaNameResolver();
2421

hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/JdbcEnvironmentImpl.java

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import java.sql.SQLException;
99

1010
import org.hibernate.boot.model.naming.Identifier;
11+
import org.hibernate.boot.registry.selector.spi.StrategySelector;
1112
import org.hibernate.cfg.AvailableSettings;
1213
import org.hibernate.dialect.Dialect;
1314
import org.hibernate.engine.config.spi.ConfigurationService;
@@ -21,6 +22,7 @@
2122
import org.hibernate.engine.jdbc.env.spi.LobCreatorBuilder;
2223
import org.hibernate.engine.jdbc.env.spi.NameQualifierSupport;
2324
import org.hibernate.engine.jdbc.env.spi.QualifiedObjectNameFormatter;
25+
import org.hibernate.engine.jdbc.env.spi.SchemaNameResolver;
2426
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
2527
import org.hibernate.exception.internal.SQLExceptionTypeDelegate;
2628
import org.hibernate.exception.internal.SQLStateConversionDelegate;
@@ -292,7 +294,7 @@ public JdbcEnvironmentImpl(
292294
this.extractedMetaDataSupport =
293295
new ExtractedDatabaseMetaDataImpl.Builder( this, true, jdbcConnectionAccess )
294296
.apply( databaseMetaData )
295-
.setConnectionSchemaName( determineCurrentSchemaName( databaseMetaData ) )
297+
.setConnectionSchemaName( determineCurrentSchemaName( databaseMetaData, serviceRegistry, dialect ) )
296298
.setSupportsNamedParameters( dialect.supportsNamedParameters( databaseMetaData ) )
297299
.build();
298300

@@ -328,16 +330,37 @@ private static IdentifierHelper identifierHelper(
328330
return identifierHelperBuilder.build();
329331
}
330332

331-
private String determineCurrentSchemaName(DatabaseMetaData databaseMetaData) {
333+
public static final String SCHEMA_NAME_RESOLVER = "hibernate.schema_name_resolver";
334+
335+
/**
336+
* @deprecated Only needed any longer for Sybase + jTDS driver combo
337+
*/
338+
@Deprecated
339+
private String determineCurrentSchemaName(
340+
DatabaseMetaData databaseMetaData,
341+
ServiceRegistry serviceRegistry,
342+
Dialect dialect) {
343+
final SchemaNameResolver resolver = getSchemaNameResolver( serviceRegistry, dialect );
332344
try {
333-
return databaseMetaData.getConnection().getSchema();
345+
return resolver.resolveSchemaName( databaseMetaData.getConnection(), dialect );
334346
}
335347
catch (Exception e) {
336348
log.debug( "Unable to resolve connection default schema", e );
337349
return null;
338350
}
339351
}
340352

353+
private static SchemaNameResolver getSchemaNameResolver(ServiceRegistry serviceRegistry, Dialect dialect) {
354+
final Object setting =
355+
serviceRegistry.requireService( ConfigurationService.class )
356+
.getSettings().get( SCHEMA_NAME_RESOLVER );
357+
return setting == null
358+
? dialect.getSchemaNameResolver()
359+
: serviceRegistry.requireService( StrategySelector.class )
360+
.resolveDefaultableStrategy( SchemaNameResolver.class, setting,
361+
dialect.getSchemaNameResolver() );
362+
}
363+
341364
private static SqlExceptionHelper buildSqlExceptionHelper(Dialect dialect, boolean logWarnings) {
342365
final SQLExceptionConversionDelegate dialectDelegate = dialect.buildSQLExceptionConversionDelegate();
343366
final SQLExceptionConversionDelegate[] delegates = dialectDelegate == null

hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/spi/JdbcEnvironment.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ public interface JdbcEnvironment extends Service {
4848
* {@link java.sql.Connection#getSchema()} or
4949
* {@value org.hibernate.cfg.AvailableSettings#DEFAULT_SCHEMA}.
5050
*
51+
* @see org.hibernate.engine.jdbc.spi.SchemaNameResolver
52+
*
5153
* @return The current schema
5254
*/
5355
Identifier getCurrentSchema();

hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/spi/SchemaNameResolver.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@
1212
/**
1313
* Contract for resolving the schema of a {@link Connection}.
1414
*
15-
* @deprecated Since Hibernate now baselines on Java 17,
16-
* {@link Connection#getSchema()} is always available directly.
15+
* @implNote Since Hibernate baselines on Java 17+, this should no longer be
16+
* needed as we should be able to rely on {@link Connection#getSchema()}.
17+
* However, some drivers still do not implement this or implement it "properly".
1718
*
1819
* @author Steve Ebersole
1920
*/
20-
@Deprecated
2121
public interface SchemaNameResolver {
2222
/**
2323
* Given a JDBC {@link Connection}, resolve the name of the schema (if one) to which it connects.

hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/SchemaNameResolver.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@
99
/**
1010
* Contract for resolving the schema of a {@link Connection}.
1111
*
12+
* @apiNote Exists mainly for historical reasons when Hibernate
13+
* baselines on Java versions before 8 when {@linkplain Connection#getSchema()}
14+
* was introduced. We still use it at the moment because some drivers do not
15+
* implement it (jTDS) and/or some databases do not support schemas and
16+
* their drivers don't DoTheRightThing.
17+
*
1218
* @author Steve Ebersole
1319
*/
1420
public interface SchemaNameResolver {

0 commit comments

Comments
 (0)