diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/JdbcSettings.java b/hibernate-core/src/main/java/org/hibernate/cfg/JdbcSettings.java index 8f0f628a9d76..2ae730b7e75a 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/JdbcSettings.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/JdbcSettings.java @@ -490,6 +490,21 @@ public interface JdbcSettings extends C3p0Settings, ProxoolSettings, AgroalSetti */ String ALLOW_METADATA_ON_BOOT = "hibernate.boot.allow_jdbc_metadata_access"; + /** + * Whether failures to access the JDBC {@linkplain java.sql.DatabaseMetaData metadata} should be ignored and the + * bootstrapping process should continue. Hibernate then uses a default JDBC + * {@linkplain org.hibernate.engine.jdbc.env.spi.JdbcEnvironment environment}. + *
+ * Failures to access the metadata can result in unexpected runtime errors when accessing the database, since the + * default JDBC environment might not correctly represent the capabilities of the underlying database. + * + * This setting only takes effect when the {@link #ALLOW_METADATA_ON_BOOT} setting is activated. + * + * @settingDefault {@code true} + * @see #ALLOW_METADATA_ON_BOOT + * @since 6.6 + */ + String IGNORE_METADATA_ACCESS_FAILURE_ON_BOOT = "hibernate.boot.ignore_jdbc_metadata_access_failure"; // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Deprecated Hibernate settings diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/JdbcEnvironmentInitiator.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/JdbcEnvironmentInitiator.java index 7038b1aa9fc3..ecc9492c96b8 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/JdbcEnvironmentInitiator.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/JdbcEnvironmentInitiator.java @@ -13,13 +13,13 @@ import java.util.Map; import java.util.StringTokenizer; +import org.hibernate.HibernateException; import org.hibernate.boot.registry.StandardServiceInitiator; import org.hibernate.cfg.JdbcSettings; import org.hibernate.dialect.DatabaseVersion; import org.hibernate.dialect.Dialect; import org.hibernate.engine.config.spi.ConfigurationService; import org.hibernate.engine.jdbc.batch.spi.BatchBuilder; -import org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator; import org.hibernate.engine.jdbc.connections.internal.DatabaseConnectionInfoImpl; import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; import org.hibernate.engine.jdbc.connections.spi.DatabaseConnectionInfo; @@ -321,7 +321,7 @@ private JdbcEnvironmentImpl getJdbcEnvironmentUsingJdbcMetadata( return temporaryJdbcSessionOwner.transactionCoordinator.createIsolationDelegate().delegateWork( new AbstractReturningWork<>() { @Override - public JdbcEnvironmentImpl execute(Connection connection) { + public JdbcEnvironmentImpl execute(Connection connection) throws SQLException { try { final DatabaseMetaData metadata = connection.getMetaData(); logDatabaseAndDriver( metadata ); @@ -357,7 +357,12 @@ public JdbcEnvironmentImpl execute(Connection connection) { ); } catch (SQLException e) { - log.unableToObtainConnectionMetadata( e ); + if ( shouldIgnoreMetadataAccessFailure( configurationValues ) ) { + log.unableToObtainConnectionMetadata( e ); + } + else { + throw e; + } } // accessing the JDBC metadata failed @@ -387,12 +392,25 @@ private int databaseMicroVersion(DatabaseMetaData metadata) throws SQLException ); } catch ( Exception e ) { - log.unableToObtainConnectionToQueryMetadata( e ); + if ( shouldIgnoreMetadataAccessFailure( configurationValues ) ) { + log.unableToObtainConnectionToQueryMetadata( e ); + } + else { + throw new HibernateException( "Unable to access JDBC metadata", e ); + } } // accessing the JDBC metadata failed return getJdbcEnvironmentWithDefaults( configurationValues, registry, dialectFactory ); } + private static boolean shouldIgnoreMetadataAccessFailure(Map