diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/DialectSpecificSettings.java b/hibernate-core/src/main/java/org/hibernate/cfg/DialectSpecificSettings.java index aee487e96fa8..384306c33243 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/DialectSpecificSettings.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/DialectSpecificSettings.java @@ -15,13 +15,18 @@ public interface DialectSpecificSettings { /** * Specifies whether this database is running on an Autonomous Database Cloud Service. + *
+ * Ignored if Hibernate is able to determine this by querying the Oracle server at startup. * * @settingDefault {@code false} */ String ORACLE_AUTONOMOUS_DATABASE = "hibernate.dialect.oracle.is_autonomous"; /** - * Specifies whether this database's {@code MAX_STRING_SIZE} is set to {@code EXTENDED}. + * Specifies whether {@code MAX_STRING_SIZE} is set to {@code EXTENDED} on Oracle. + *
+ * Ignored if Hibernate is able to determine the value of {@code MAX_STRING_SIZE} by + * querying the Oracle server at startup. * * @settingDefault {@code false} */ @@ -29,6 +34,8 @@ public interface DialectSpecificSettings { /** * Specifies whether this database is accessed using a database service protected by Application Continuity. + *
+ * Ignored if Hibernate is able to determine this by querying the Oracle server at startup. * * @settingDefault {@code false} * @@ -37,7 +44,10 @@ public interface DialectSpecificSettings { String ORACLE_APPLICATION_CONTINUITY = "hibernate.dialect.oracle.application_continuity"; /** - * Specifies whether this database's {@code ansinull} setting is enabled. + * Specifies whether the {@code ansinull} setting is enabled on Sybase. + *
+ * Ignored if Hibernate is able to determine the value of {@code ansinull} + * by querying the server {@code @@options} at startup. * * @settingDefault {@code false} */ @@ -45,6 +55,9 @@ public interface DialectSpecificSettings { /** * Specifies the maximum page size on Sybase. + *
+ * Ignored if Hibernate is able to determine the page size by querying the + * server {@code @@maxpagesize} at startup. * * @settingDefault {@value org.hibernate.dialect.SybaseASEDialect#MAX_PAGE_SIZE} */ @@ -53,6 +66,9 @@ public interface DialectSpecificSettings { /** * Specifies the bytes per character to use based on the database's configured * charset. + *
+ * Ignored if Hibernate is able to determine the character set by querying the + * server {@code @@character_set_database} at startup. * * @settingDefault {@code 4} */ @@ -60,6 +76,9 @@ public interface DialectSpecificSettings { /** * Specifies whether the {@code NO_BACKSLASH_ESCAPES} sql mode is enabled. + *
+ * Ignored if Hibernate is able to determine this by querying the server + * {@code @@sql_mode} at startup. * * @settingDefault {@code false} */ @@ -69,18 +88,28 @@ public interface DialectSpecificSettings { * Specifies a custom CockroachDB version string. The expected format of the string is * the one returned from the {@code version()} function, e.g.: * {@code "CockroachDB CCL v23.1.8 (x86_64-pc-linux-gnu, built 2023/08/04 18:11:44, go1.19.10)"} + *
+ * Ignored if Hibernate is able to obtain the version string by querying the server at startup. */ String COCKROACH_VERSION_STRING = "hibernate.dialect.cockroach.version_string"; /** - * Specifies the compatibility level of the SQL Server database as returned by {@code select compatibility_level from sys.databases}. - * The number has three digits, the first two digits are the major version, the last digit is the minor version. + * Specifies the compatibility level of the SQL Server database as returned by + * {@code select compatibility_level from sys.databases}. + *
+ * The number has three digits: the first two digits are the major version, + * the last digit is the minor version. + *
+ * Ignored if Hibernate is able to determine this by querying the {@code sys.databases} + * table at startup. */ String SQL_SERVER_COMPATIBILITY_LEVEL = "hibernate.dialect.sqlserver.compatibility_level"; /** - * Specifies the LOB prefetch size. LOBs larger than this value will be read into memory as the HANA JDBC driver closes - * the LOB when the result set is closed. + * Specifies the LOB prefetch size. LOBs larger than this value will be read into + * memory as the HANA JDBC driver closes the LOB when the result set is closed. + *
+ * Ignored if Hibernate is able to determine this by querying the server at startup.
*
* @settingDefault {@code 1024}
*/
diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java
index d037b39bb5a1..690f32dce88b 100644
--- a/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java
+++ b/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java
@@ -20,7 +20,9 @@
import org.hibernate.PessimisticLockException;
import org.hibernate.boot.model.FunctionContributions;
import org.hibernate.boot.model.TypeContributions;
+import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Environment;
+import org.hibernate.cfg.FetchSettings;
import org.hibernate.dialect.aggregate.AggregateSupport;
import org.hibernate.dialect.aggregate.MySQLAggregateSupport;
import org.hibernate.dialect.function.CommonFunctionFactory;
@@ -45,7 +47,6 @@
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor;
import org.hibernate.exception.spi.ViolatedConstraintNameExtractor;
-import org.hibernate.internal.util.StringHelper;
import org.hibernate.mapping.CheckConstraint;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
@@ -89,6 +90,7 @@
import static org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor.extractUsingTemplate;
import static org.hibernate.internal.util.JdbcExceptionHelper.extractSqlState;
import static org.hibernate.internal.util.StringHelper.isNotEmpty;
+import static org.hibernate.internal.util.StringHelper.split;
import static org.hibernate.type.SqlTypes.BIGINT;
import static org.hibernate.type.SqlTypes.BINARY;
import static org.hibernate.type.SqlTypes.BIT;
@@ -217,7 +219,7 @@ protected static DatabaseVersion createVersion(DialectResolutionInfo info) {
protected static DatabaseVersion createVersion(DialectResolutionInfo info, DatabaseVersion defaultVersion) {
final String versionString = info.getDatabaseVersion();
if ( versionString != null ) {
- final String[] components = StringHelper.split( ".-", versionString );
+ final String[] components = split( ".-", versionString );
if ( components.length >= 3 ) {
try {
final int majorVersion = parseInt( components[0] );
@@ -241,26 +243,19 @@ protected DatabaseVersion getMinimumSupportedVersion() {
@Override
protected void initDefaultProperties() {
super.initDefaultProperties();
- getDefaultProperties().setProperty( Environment.MAX_FETCH_DEPTH, "2" );
+ getDefaultProperties().setProperty( FetchSettings.MAX_FETCH_DEPTH, "2" );
}
private MySQLStorageEngine createStorageEngine() {
- String storageEngine = Environment.getProperties().getProperty( Environment.STORAGE_ENGINE );
- if (storageEngine == null) {
- storageEngine = System.getProperty( Environment.STORAGE_ENGINE );
- }
- if (storageEngine == null) {
- return getDefaultMySQLStorageEngine();
- }
- else if( "innodb".equalsIgnoreCase( storageEngine ) ) {
- return InnoDBStorageEngine.INSTANCE;
- }
- else if( "myisam".equalsIgnoreCase( storageEngine ) ) {
- return MyISAMStorageEngine.INSTANCE;
- }
- else {
- throw new UnsupportedOperationException( "The " + storageEngine + " storage engine is not supported" );
- }
+ final String storageEngine = Environment.getProperties().getProperty( AvailableSettings.STORAGE_ENGINE );
+ return storageEngine == null
+ ? getDefaultMySQLStorageEngine()
+ : switch ( storageEngine ) {
+ case "innodb" -> InnoDBStorageEngine.INSTANCE;
+ case "myisam" -> MyISAMStorageEngine.INSTANCE;
+ default -> throw new UnsupportedOperationException(
+ "The '" + storageEngine + "' storage engine is not supported" );
+ };
}
@Override
diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/OracleDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/OracleDialect.java
index e94bc41125a7..e1afde5658dc 100644
--- a/hibernate-core/src/main/java/org/hibernate/dialect/OracleDialect.java
+++ b/hibernate-core/src/main/java/org/hibernate/dialect/OracleDialect.java
@@ -34,8 +34,6 @@
import org.hibernate.dialect.temptable.TemporaryTableKind;
import org.hibernate.dialect.unique.CreateTableUniqueDelegate;
import org.hibernate.dialect.unique.UniqueDelegate;
-import org.hibernate.engine.config.spi.ConfigurationService;
-import org.hibernate.engine.config.spi.StandardConverters;
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
import org.hibernate.engine.jdbc.env.spi.IdentifierHelperBuilder;
@@ -86,7 +84,6 @@
import org.hibernate.type.NullType;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.java.PrimitiveByteArrayJavaType;
-import org.hibernate.type.descriptor.jdbc.BlobJdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.NullJdbcType;
import org.hibernate.type.descriptor.jdbc.ObjectNullAsNullTypeJdbcType;
@@ -108,8 +105,6 @@
import static org.hibernate.LockOptions.SKIP_LOCKED;
import static org.hibernate.LockOptions.WAIT_FOREVER;
import static org.hibernate.cfg.AvailableSettings.BATCH_VERSIONED_DATA;
-import static org.hibernate.cfg.DialectSpecificSettings.ORACLE_EXTENDED_STRING_SIZE;
-import static org.hibernate.cfg.DialectSpecificSettings.ORACLE_AUTONOMOUS_DATABASE;
import static org.hibernate.dialect.OracleJdbcHelper.getArrayJdbcTypeConstructor;
import static org.hibernate.dialect.OracleJdbcHelper.getNestedTableJdbcTypeConstructor;
import static org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor.extractUsingTemplate;
@@ -168,12 +163,11 @@ public class OracleDialect extends Dialect {
private static final Pattern SQL_STATEMENT_TYPE_PATTERN =
Pattern.compile( "^(?:/\\*.*?\\*/)?\\s*(select|insert|update|delete)\\s+.*?", CASE_INSENSITIVE );
- private static final int PARAM_LIST_SIZE_LIMIT_1000 = 1000;
-
- /** Starting from 23c, 65535 parameters are supported for the IN condition. */
+ /**
+ * Starting from 23c, 65535 parameters are supported for the {@code IN} condition.
+ */
private static final int PARAM_LIST_SIZE_LIMIT_65535 = 65535;
-
- public static final String PREFER_LONG_RAW = "hibernate.dialect.oracle.prefer_long_raw";
+ private static final int PARAM_LIST_SIZE_LIMIT_1000 = 1000;
private static final String yqmSelect =
"(trunc(%2$s, 'MONTH') + numtoyminterval(%1$s, 'MONTH') + (least(extract(day from %2$s), extract(day from last_day(trunc(%2$s, 'MONTH') + numtoyminterval(%1$s, 'MONTH')))) - 1))";
@@ -191,11 +185,10 @@ public class OracleDialect extends Dialect {
@Override
protected void applyAggregateColumnCheck(StringBuilder buf, AggregateColumn aggregateColumn) {
final JdbcType jdbcType = aggregateColumn.getType().getJdbcType();
- if ( dialect.getVersion().isBefore( 23, 6 ) && jdbcType.isXml() ) {
- // ORA-00600 when selecting XML columns that have a check constraint was fixed in 23.6
- return;
+ // ORA-00600 when selecting XML columns that have a check constraint was fixed in 23.6
+ if ( !dialect.getVersion().isBefore( 23, 6 ) || !jdbcType.isXml() ) {
+ super.applyAggregateColumnCheck( buf, aggregateColumn );
}
- super.applyAggregateColumnCheck( buf, aggregateColumn );
}
};
@@ -239,40 +232,6 @@ public OracleDialect(DialectResolutionInfo info, OracleServerConfiguration serve
this.driverMajorVersion = serverConfiguration.getDriverMajorVersion();
}
- @Deprecated( since = "6.4" )
- protected static boolean isExtended(DialectResolutionInfo info) {
- final DatabaseMetaData databaseMetaData = info.getDatabaseMetadata();
- if ( databaseMetaData != null ) {
- try ( java.sql.Statement statement = databaseMetaData.getConnection().createStatement() ) {
- statement.execute( "select cast('string' as varchar2(32000)) from dual" );
- // succeeded, so MAX_STRING_SIZE == EXTENDED
- return true;
- }
- catch ( SQLException ex ) {
- // failed, so MAX_STRING_SIZE == STANDARD
- // Ignore
- }
- }
- // default to the dialect-specific configuration setting
- return ConfigurationHelper.getBoolean( ORACLE_EXTENDED_STRING_SIZE, info.getConfigurationValues(), false );
- }
-
- @Deprecated( since = "6.4" )
- protected static boolean isAutonomous(DialectResolutionInfo info) {
- final DatabaseMetaData databaseMetaData = info.getDatabaseMetadata();
- if ( databaseMetaData != null ) {
- try ( java.sql.Statement statement = databaseMetaData.getConnection().createStatement() ) {
- return statement.executeQuery( "select 1 from dual where sys_context('USERENV','CLOUD_SERVICE') in ('OLTP','DWCS','JSON')" )
- .next();
- }
- catch ( SQLException ex ) {
- // Ignore
- }
- }
- // default to the dialect-specific configuration setting
- return ConfigurationHelper.getBoolean( ORACLE_AUTONOMOUS_DATABASE, info.getConfigurationValues(), false );
- }
-
public boolean isAutonomous() {
return autonomous;
}
@@ -360,12 +319,12 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
functionFactory.coalesce();
functionContributions.getFunctionRegistry()
- .patternDescriptorBuilder( "bitor", "(?1+?2-bitand(?1,?2))")
+ .patternDescriptorBuilder( "bitor", "(?1+?2-bitand(?1,?2))" )
.setExactArgumentCount( 2 )
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE )
.register();
functionContributions.getFunctionRegistry()
- .patternDescriptorBuilder( "bitxor", "(?1+?2-2*bitand(?1,?2))")
+ .patternDescriptorBuilder( "bitxor", "(?1+?2-2*bitand(?1,?2))" )
.setExactArgumentCount( 2 )
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE )
.register();
@@ -1019,12 +978,6 @@ public void contributeTypes(TypeContributions typeContributions, ServiceRegistry
typeContributions.contributeJdbcType( OracleReflectionStructJdbcType.INSTANCE );
}
- // account for Oracle's deprecated support for LONGVARBINARY
- // prefer BLOB, unless the user explicitly opts out
- final boolean preferLong = serviceRegistry.requireService( ConfigurationService.class )
- .getSetting( PREFER_LONG_RAW, StandardConverters.BOOLEAN, false );
- typeContributions.contributeJdbcType( preferLong ? BlobJdbcType.PRIMITIVE_ARRAY_BINDING : BlobJdbcType.DEFAULT );
-
if ( getVersion().isSameOrAfter( 21 ) ) {
typeContributions.contributeJdbcType( OracleJsonJdbcType.INSTANCE );
typeContributions.contributeJdbcTypeConstructor( OracleJsonArrayJdbcTypeConstructor.NATIVE_INSTANCE );
@@ -1065,10 +1018,10 @@ public void contributeTypes(TypeContributions typeContributions, ServiceRegistry
)
);
- if(getVersion().isSameOrAfter(23)) {
+ if ( getVersion().isSameOrAfter(23) ) {
final JdbcTypeRegistry jdbcTypeRegistry = typeContributions.getTypeConfiguration().getJdbcTypeRegistry();
- jdbcTypeRegistry.addDescriptor(OracleEnumJdbcType.INSTANCE);
- jdbcTypeRegistry.addDescriptor(OracleOrdinalEnumJdbcType.INSTANCE);
+ jdbcTypeRegistry.addDescriptor( OracleEnumJdbcType.INSTANCE );
+ jdbcTypeRegistry.addDescriptor( OracleOrdinalEnumJdbcType.INSTANCE );
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/OracleServerConfiguration.java b/hibernate-core/src/main/java/org/hibernate/dialect/OracleServerConfiguration.java
index 32a188a9e5b5..7b73e06ec416 100644
--- a/hibernate-core/src/main/java/org/hibernate/dialect/OracleServerConfiguration.java
+++ b/hibernate-core/src/main/java/org/hibernate/dialect/OracleServerConfiguration.java
@@ -4,21 +4,22 @@
*/
package org.hibernate.dialect;
-import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
+import java.sql.Driver;
+import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
-import java.util.List;
+import java.util.Map;
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
-import org.hibernate.internal.util.config.ConfigurationHelper;
import static org.hibernate.cfg.DialectSpecificSettings.ORACLE_APPLICATION_CONTINUITY;
import static org.hibernate.cfg.DialectSpecificSettings.ORACLE_AUTONOMOUS_DATABASE;
import static org.hibernate.cfg.DialectSpecificSettings.ORACLE_EXTENDED_STRING_SIZE;
+import static org.hibernate.internal.util.config.ConfigurationHelper.getBoolean;
/**
* Utility class that extract some initial configuration from the database for {@link OracleDialect}.
@@ -62,7 +63,7 @@ public OracleServerConfiguration(
boolean extended,
int driverMajorVersion,
int driverMinorVersion) {
- this(autonomous, extended, false, driverMajorVersion, driverMinorVersion);
+ this( autonomous, extended, false, driverMajorVersion, driverMinorVersion );
}
public OracleServerConfiguration(
@@ -79,103 +80,25 @@ public OracleServerConfiguration(
}
public static OracleServerConfiguration fromDialectResolutionInfo(DialectResolutionInfo info) {
- Boolean extended = null;
- Boolean autonomous = null;
- Boolean applicationContinuity = null;
- Integer majorVersion = null;
- Integer minorVersion = null;
- final DatabaseMetaData databaseMetaData = info.getDatabaseMetadata();
- if ( databaseMetaData != null ) {
- majorVersion = databaseMetaData.getDriverMajorVersion();
- minorVersion = databaseMetaData.getDriverMinorVersion();
-
- try {
- final Connection c = databaseMetaData.getConnection();
-
- try (final Statement statement = c.createStatement()) {
-
- // Use Oracle JDBC replay statistics information to determine if this
- // connection is protected by Application Continuity
- try {
- final Class statisticReportTypeEnum = Class.forName("oracle.jdbc.replay.ReplayableConnection$StatisticsReportType",false, Thread.currentThread().getContextClassLoader());
- final Field forCurrentConnection = statisticReportTypeEnum.getField("FOR_CURRENT_CONNECTION");
-
- final Method getReplayStatistics = c.getClass().getMethod("getReplayStatistics", statisticReportTypeEnum);
-
- Object stats = getReplayStatistics.invoke(c,forCurrentConnection.get(null));
-
- final Method getTotalRequests = stats.getClass().getMethod("getTotalRequests");
- final Method getTotalProtectedCalls = stats.getClass().getMethod("getTotalProtectedCalls");
-
- final Long totalRequestsBefore = (Long)getTotalRequests.invoke(stats);
- final Long protectedCallsBefore = (Long)getTotalProtectedCalls.invoke(stats);
-
- try (ResultSet r = statement.executeQuery("select 1")) {
- r.next();
- }
-
- stats = getReplayStatistics.invoke(c,forCurrentConnection.get(null));
-
- final Long totalRequestsAfter = (Long)getTotalRequests.invoke(stats);
- final Long protectedCallsAfter = (Long)getTotalProtectedCalls.invoke(stats);
-
- // Application continuity is enabled on this database service if the number of
- // total requests and the number of protected calls for this connection have
- // both increased.
- applicationContinuity = totalRequestsAfter > totalRequestsBefore && protectedCallsAfter > protectedCallsBefore;
- }
- catch(Exception e) {
- // A ClassCastException or a NullPointerException are expected here in the case
- // the Connection Factory is not the right one (not Replayable: ClassCastException)
- // or if the database service has not been configured (server side) to enable
- // application continuity (NullPointerException).
- applicationContinuity = false;
- }
-
- // continue the checks...
- final ResultSet rs = statement.executeQuery(
- "select cast('string' as varchar2(32000)), " +
- "sys_context('USERENV','CLOUD_SERVICE') from dual"
- );
- if (rs.next()) {
- // succeeded, so MAX_STRING_SIZE == EXTENDED
- extended = true;
- autonomous = isAutonomous(rs.getString(2));
- }
- }
- }
- catch (SQLException ex) {
- // failed, so MAX_STRING_SIZE == STANDARD, still need to check autonomous
- extended = false;
- autonomous = isAutonomous( databaseMetaData );
- }
- }
// default to the dialect-specific configuration settings
- if ( extended == null ) {
- extended = ConfigurationHelper.getBoolean(
- ORACLE_EXTENDED_STRING_SIZE,
- info.getConfigurationValues(),
- false
- );
- }
- if ( autonomous == null ) {
- autonomous = ConfigurationHelper.getBoolean(
- ORACLE_AUTONOMOUS_DATABASE,
- info.getConfigurationValues(),
- false
- );
- }
- if ( applicationContinuity == null ) {
- applicationContinuity = ConfigurationHelper.getBoolean(
- ORACLE_APPLICATION_CONTINUITY,
- info.getConfigurationValues(),
- false
- );
- }
- if ( majorVersion == null ) {
+ final Map