Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HHH-18286 Add Setting to fail Bootstrapping on Metadata Access Failure #8957

Open
wants to merge 1 commit into
base: 6.6
Choose a base branch
from

Conversation

dnl50
Copy link

@dnl50 dnl50 commented Sep 15, 2024

A failure to access the JDBC connection metadata while bootstrapping Hibernate can lead to ClassCastExceptions during runtime when the Oracle JDBC driver is used and a BLOB is created by the NonContextualLobCreator. To avoid this issue, a new JDBC setting is introduced, which lets the bootstrapping fail when the connection metadata cannot be obtained.


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license
and can be relicensed under the terms of the LGPL v2.1 license in the future at the maintainers' discretion.
For more information on licensing, please check here.


https://hibernate.atlassian.net/browse/HHH-18286

A failure to access the JDBC connection metadata while bootstrapping
Hibernate can lead to ClassCastExceptions during runtime when the
Oracle JDBC driver is used and a BLOB is created by the
NonContextualLobCreator. To avoid this issue, a new JDBC setting is
introduced, which lets the bootstrapping fail when the connection
metadata cannot be obtained.
@@ -357,7 +357,12 @@ public JdbcEnvironmentImpl execute(Connection connection) {
);
}
catch (SQLException e) {
log.unableToObtainConnectionMetadata( e );
if ( shouldIgnoreMetadataAccessFailure( configurationValues ) ) {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test case I added in MetadataAccessTests doesn't cover this case, since an actual JDBC connection is required and the Connection#getMetaData method needs to throw a SQLException to reach it. I didn't really know how to make this happen ☹️

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I achieved this by mocking the ConnectionProvider and the returned Connection, but this is pretty dependent on the actual implementation of the JdbcEnvironmentInitiator:

@Test
@Jira("https://hibernate.atlassian.net/browse/HHH-18286")
void testDontIgnoreMetadataAccessFailureWhenConnectionCanBeObtained() throws Exception {
	Connection connectionMock = Mockito.mock( Connection.class );
	given( connectionMock.getMetaData() ).willThrow( new SQLException( "Connection closed unexpectedly!" ) );

	ConnectionProvider connectionProviderMock = Mockito.mock( ConnectionProvider.class );
	given( connectionProviderMock.getConnection() ).willReturn( connectionMock );

	StandardServiceRegistryBuilder registryBuilder = new StandardServiceRegistryBuilder();
	registryBuilder.clearSettings();
	registryBuilder.applySetting( JdbcSettings.IGNORE_METADATA_ACCESS_FAILURE_ON_BOOT, false )
			.applySetting( AvailableSettings.CONNECTION_PROVIDER, connectionProviderMock );

	try (StandardServiceRegistry registry = registryBuilder.build()) {
		assertThatExceptionOfType( ServiceException.class )
				.isThrownBy( () -> registry.getService( JdbcEnvironment.class ) )
				.withRootCauseInstanceOf( SQLException.class )
				.havingCause()
				.isInstanceOf( HibernateException.class )
				.withMessage( "Unable to access JDBC metadata" );
	}
}

The QualifiedTableNamingTest has a MockedConnectionProvider implementation of the ConnectionProvider interface, which uses the JdbcMocks factory class, but that uses dynamic proxies which do not throw a SQLException but actually return a result when calling the Connection#getMetaData method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant