Custom ConnectionProvider with DataDirect driver not working in Hibernate 5.4

In a Java Application using DataDirect with Hibernate 5.4.18. Since the DataDirect driver (branded) needs to be unlocked, wrote a customer ConnectionProvider implementation. But the implementation is not getting invoked. Getting the following error:

Dec 02, 2020 7:56:13 AM org.hibernate.Version logVersion INFO: HHH000412: Hibernate ORM core version 5.4.18.Final
Dec 02, 2020 7:56:14 AM org.hibernate.engine.jdbc.spi.TypeInfo extractTypeInfo WARN: HHH000362: Unable to retrieve type info result set : java.sql.SQLException: [PostgreSQL JDBC Driver]This driver is locked for use with embedded applications. Dec 02, 2020 7:56:15 AM org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentImpl sequenceInformationList ERROR: Could not fetch the SequenceInformation from the database java.sql.SQLException: [PostgreSQL JDBC Driver]This driver is locked for use with embedded applications. at com.wm.dd.jdbc.postgresqlbase.ddcp.b(Unknown Source) at com.wm.dd.jdbc.postgresqlbase.ddcp.a(Unknown Source) at com.wm.dd.jdbc.postgresqlbase.ddco.b(Unknown Source) at com.wm.dd.jdbc.postgresqlbase.ddco.a(Unknown Source) at com.wm.dd.jdbc.postgresqlbase.BaseConnection.createStatement(Unknown Source) at com.wm.dd.jdbc.postgresqlbase.BaseConnection.createStatement(Unknown Source) at org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl.extractMetadata(SequenceInformationExtractorLegacyImpl.java:40) at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentImpl.sequenceInformationList(JdbcEnvironmentImpl.java:403) at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentImpl.(JdbcEnvironmentImpl.java:268) at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:114) at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35) at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:101) at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263) at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237) at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214) at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.injectServices(DefaultIdentifierGeneratorFactory.java:152) at org.hibernate.service.internal.AbstractServiceRegistryImpl.injectDependencies(AbstractServiceRegistryImpl.java:286) at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:243) at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214) at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.(InFlightMetadataCollectorImpl.java:176) at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:118) at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:83) at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:473) at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:84) at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:689) at com.venkat.jdbc.JDBCManager.(JDBCManager.java:44) at com.venkat.jdbc.JDBCManager.main(JDBCManager.java:55)
Dec 02, 2020 7:56:15 AM org.hibernate.engine.jdbc.spi.TypeInfo extractTypeInfo WARN: HHH000362: Unable to retrieve type info result set : java.sql.SQLException: [PostgreSQL JDBC Driver]This driver is locked for use with embedded applications. SessionImpl(802771878)

My Connection Provider implementation

private class HibernateConnProvider implements ConnectionProvider {
private static final long serialVersionUID = -7281450846523561184L;
private ConnectionProvider provider;

HibernateConnProvider(ConnectionProvider delegate) {
    this.provider = delegate;
}

@Override
public boolean isUnwrappableAs(Class unwrapType) {
    return this.provider.isUnwrappableAs(unwrapType);
}

@Override
public <T> T unwrap(Class<T> unwrapType) {
    return this.provider.unwrap(unwrapType);
}

@Override
public Connection getConnection() throws SQLException {
    try {
        Connection result = this.provider.getConnection();
        Class<?> clazz = Class.forName("com.ddtek.jdbc.extensions.ExtEmbeddedConnection");

        Field field = result.getClass().getDeclaredField("inner");
        field.setAccessible(true);
        Object jdbcConnection = field.get(result);

        if (clazz.isAssignableFrom(jdbcConnection.getClass())) {
            System.out.println("Unlocking database embedded jdbc driver.");
            Method method = clazz.getMethod("unlock", String.class);
            method.invoke(jdbcConnection, "driver_passkey");
        }
        return result;
    } catch (Exception e) {
        throw new SQLException(e);
    }
}

@Override
public void closeConnection(Connection conn) throws SQLException {
    this.provider.closeConnection(conn);
}

@Override
public boolean supportsAggressiveRelease() {
    return this.provider.supportsAggressiveRelease();
}

}

Connection Provider invocation snippet is as follows:

        Properties settings = new Properties(); 
        settings.put(Environment.DRIVER, "com.wm.dd.jdbc.postgresql.PostgreSQLDriver");
        settings.put(Environment.URL, "jdbc:wm:postgresql://localhost:5432;DatabaseName=postgres");
        settings.put(Environment.USER, "dev_user");
        settings.put(Environment.PASS, "dev_user");
        settings.put(Environment.DIALECT, "org.hibernate.dialect.PostgreSQL95Dialect");
        settings.put(Environment.SHOW_SQL, "false");
        settings.put(Environment.CURRENT_SESSION_CONTEXT_CLASS, "thread");
        settings.put(Environment.CACHE_PROVIDER_CONFIG, "org.hibernate.cache.internal.NoCachingRegionFactory");
        
        config.setProperties(settings);
        
        try {
            ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(config.getProperties())
 .build();

            ConnectionProvider connProvider = serviceRegistry.getService(ConnectionProvider.class);
            config.getStandardServiceRegistryBuilder().addService(ConnectionProvider.class, new HibernateConnProvider(connProvider)); 

            factory = config.buildSessionFactory(serviceRegistry);
        } catch (Exception e) {
            e.printStackTrace();
        }

Is there anything I’m missing in ConnectionProvider implementation? Anybody faced similar issue? Any help would be appreciated.

PS: When I attempt the unlock code-block with JDBC APIs/unbranded driver, it works perfectly fine.

As you can see in the documentation, you need to register the connection provider class name in the settings as hibernate.connection.provider_class: https://docs.jboss.org/hibernate/stable/orm/userguide/html_single/Hibernate_User_Guide.html#database-connectionprovider

Thanks for the reply.
If I declare the implementation :

settings.put(Environment.CONNECTION_PROVIDER, HibernateConnProvider.class.getCanonicalName());

I’m getting CNF error:

caused by ClassNotFoundException: Could not load class dev.venkat.jdbc.HibernateConnProvider

HibernateConnProvider is an inner class in my implementation.
Any tips to resolve?

You need to share a stack trace, otherwise it’s hard to understand why class loading fails. Since it’s an inner class, make sure it’s a static inner class and also that it is public, otherwise Hibernate can’t instantiate the provider.

Whether the inner class is static or not, the error message is same.
The stacktrace is as follows:

Dec 08, 2020 2:35:38 PM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate ORM core version 5.4.18.Final
Dec 08, 2020 2:35:38 PM org.hibernate.annotations.common.reflection.java.JavaReflectionManager
INFO: HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
Dec 08, 2020 2:35:39 PM org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator initiateService
INFO: HHH000130: Instantiating explicit connection provider: dev.venkat.jdbc.JDBCManager.HibernateConnProvider
org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.connections.spi.ConnectionProvider]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:275)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.buildJdbcConnectionAccess(JdbcEnvironmentInitiator.java:145)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:66)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:101)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.injectServices(DefaultIdentifierGeneratorFactory.java:152)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.injectDependencies(AbstractServiceRegistryImpl.java:286)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:243)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.(InFlightMetadataCollectorImpl.java:176)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:118)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:83)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:473)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:84)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:689)
at dev.venkat.jdbc.JDBCManager.(JDBCManager.java:43)
at dev.venkat.is.jdbc.JDBCManager.main(JDBCManager.java:54)
Caused by: org.hibernate.boot.registry.selector.spi.StrategySelectionException: Unable to resolve name [dev.venkat.jdbc.JDBCManager.HibernateConnProvider] as strategy [org.hibernate.engine.jdbc.connections.spi.ConnectionProvider]
at org.hibernate.boot.registry.selector.internal.StrategySelectorImpl.selectStrategyImplementor(StrategySelectorImpl.java:156)
at org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator.initiateService(ConnectionProviderInitiator.java:138)
at org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator.initiateService(ConnectionProviderInitiator.java:41)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:101)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
… 21 more
Caused by: org.hibernate.boot.registry.classloading.spi.ClassLoadingException: Unable to load class [dev.venkat.jdbc.JDBCManager.HibernateConnProvider]
at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.classForName(ClassLoaderServiceImpl.java:133)
at org.hibernate.boot.registry.selector.internal.StrategySelectorImpl.selectStrategyImplementor(StrategySelectorImpl.java:152)
… 25 more
Caused by: java.lang.ClassNotFoundException: Could not load requested class : dev.venkat.jdbc.JDBCManager.HibernateConnProvider
at org.hibernate.boot.registry.classloading.internal.AggregatedClassLoader.findClass(AggregatedClassLoader.java:210)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.classForName(ClassLoaderServiceImpl.java:130)
… 26 more

If it’s an inner class, you need to use the $ sign to separate outer and inner class, so use dev.venkat.jdbc.JDBCManager$HibernateConnProvider

Hi Beikov,

Changed the way the provider class had been represented to the one you’ve suggested.

settings.put(Environment.CONNECTION_PROVIDER, JDBCManager.class.getCanonicalName()+"$HibernateConnProvider");

Now Hibernate is looking for init() method in ConnectionProvider implmentation.

The stacktrace is as follows:

Dec 09, 2020 8:28:23 AM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate ORM core version 5.4.18.Final
Dec 09, 2020 8:28:23 AM org.hibernate.annotations.common.reflection.java.JavaReflectionManager
INFO: HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
Dec 09, 2020 8:28:24 AM org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator initiateService
INFO: HHH000130: Instantiating explicit connection provider: dev.venkat.jdbc.JDBCManager$HibernateConnProvider
org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.connections.spi.ConnectionProvider]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:275)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.buildJdbcConnectionAccess(JdbcEnvironmentInitiator.java:145)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:66)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:101)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.injectServices(DefaultIdentifierGeneratorFactory.java:152)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.injectDependencies(AbstractServiceRegistryImpl.java:286)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:243)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.(InFlightMetadataCollectorImpl.java:176)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:118)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:83)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:473)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:84)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:689)
at dev.venkat.jdbc.JDBCManager.(JDBCManager.java:43)
at dev.venkat.jdbc.JDBCManager.main(JDBCManager.java:54)
Caused by: org.hibernate.HibernateException: Could not instantiate connection provider [dev.venkat.jdbc.JDBCManager$HibernateConnProvider]
at org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator.initiateService(ConnectionProviderInitiator.java:146)
at org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator.initiateService(ConnectionProviderInitiator.java:41)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:101)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
… 21 more
Caused by: org.hibernate.HibernateException: Could not instantiate connection provider [dev.venkat.jdbc.JDBCManager$HibernateConnProvider]
at org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator.instantiateExplicitConnectionProvider(ConnectionProviderInitiator.java:253)
at org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator.initiateService(ConnectionProviderInitiator.java:143)
… 24 more
Caused by: java.lang.InstantiationException: dev.venkat.jdbc.JDBCManager$HibernateConnProvider
at java.lang.Class.newInstance(Class.java:427)
at org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator.instantiateExplicitConnectionProvider(ConnectionProviderInitiator.java:250)
… 25 more
Caused by: java.lang.NoSuchMethodException: dev.venkat.jdbc.JDBCManager$HibernateConnProvider.()
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.newInstance(Class.java:412)
… 26 more

So, I’ve changed the implementation from inner/static inner class to public class and defined settings as:

settings.put(Environment.CONNECTION_PROVIDER, HibernateConnProvider.class.getCanonicalName());

Yet the error stacktrace doesn’t have much change except the fully qualified name of HibernateConnProvider.

This is the reason why I’ve used ServiceRegistry to inject the custom ConnectionProvider implementation. Unfortunately that’s also not working.
Any help?

Well, it looks for a default constructor i.e. one without parameters to instantiate it. Do you have that?

Added that. It’s failing in both the cases : inner/static inner class and public class.

Inner/Inner static class:
Dec 09, 2020 2:23:11 PM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate ORM core version 5.4.18.Final
Dec 09, 2020 2:23:12 PM org.hibernate.annotations.common.reflection.java.JavaReflectionManager
INFO: HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
Dec 09, 2020 2:23:12 PM org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator initiateService
INFO: HHH000130: Instantiating explicit connection provider: dev.venkat.jdbc.JDBCManager$HibernateConnProvider
org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.connections.spi.ConnectionProvider]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:275)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.buildJdbcConnectionAccess(JdbcEnvironmentInitiator.java:145)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:66)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:101)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.injectServices(DefaultIdentifierGeneratorFactory.java:152)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.injectDependencies(AbstractServiceRegistryImpl.java:286)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:243)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.(InFlightMetadataCollectorImpl.java:176)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:118)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:83)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:473)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:84)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:689)
at dev.venkat.jdbc.JDBCManager.(JDBCManager.java:43)
at dev.venkat.jdbc.JDBCManager.main(JDBCManager.java:54)
Caused by: org.hibernate.HibernateException: Could not instantiate connection provider [dev.venkat.jdbc.JDBCManager$HibernateConnProvider]
at org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator.initiateService(ConnectionProviderInitiator.java:146)
at org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator.initiateService(ConnectionProviderInitiator.java:41)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:101)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
… 21 more
Caused by: org.hibernate.HibernateException: Could not instantiate connection provider [dev.venkat.jdbc.JDBCManager$HibernateConnProvider]
at org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator.instantiateExplicitConnectionProvider(ConnectionProviderInitiator.java:253)
at org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator.initiateService(ConnectionProviderInitiator.java:143)
… 24 more
Caused by: java.lang.InstantiationException: dev.venkat.jdbc.JDBCManager$HibernateConnProvider
at java.lang.Class.newInstance(Class.java:427)
at org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator.instantiateExplicitConnectionProvider(ConnectionProviderInitiator.java:250)
… 25 more
Caused by: java.lang.NoSuchMethodException: dev.venkat.jdbc.JDBCManager$HibernateConnProvider.()
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.newInstance(Class.java:412)
… 26 more

External Class:

Dec 09, 2020 2:16:09 PM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate ORM core version 5.4.18.Final
Dec 09, 2020 2:16:10 PM org.hibernate.annotations.common.reflection.java.JavaReflectionManager
INFO: HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
Dec 09, 2020 2:16:10 PM org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator initiateService
INFO: HHH000130: Instantiating explicit connection provider: dev.venkat.jdbc.util.HibernateConnProvider
Trying to unlock connection.
Trying to unlock connection.
Trying to unlock connection.
Trying to unlock connection.

I don’t know what else I can tell you. You simply don’t have a default constructor in that class. The static keyword on the class is important, as non-static inner classes get a parameter added to constructors that captures the outer object.

I don’t know what you mean by failing, but you didn’t post an exception for the external class problem, so it seems to me that it works.

Even with default constructor as a static inner class, the provider is failing with the above mentioned stacktrace.

Wish I could get more, but thats what I’ve got for when the implementation is a public class.
Basically, the flow gets into getConnection() method in this case, but call gets into recursion and the message “Trying to unlock connection” goes on.

Modified snippet:

public Connection getConnection() throws SQLException {
    try {
        Connection result = this.getConnection();
        Class<?> clazz = Class.forName("com.ddtek.jdbc.extensions.ExtEmbeddedConnection");

        Field field = result.getClass().getDeclaredField("inner");
        field.setAccessible(true);
        Object jdbcConnection = field.get(result);

        if (clazz.isAssignableFrom(jdbcConnection.getClass())) {
            System.out.println("Unlocking database embedded jdbc driver.");
            Method method = clazz.getMethod("unlock", String.class);
            method.invoke(jdbcConnection, "driver_passkey");
        }
        return result;
    } catch (Exception e) {
        throw new SQLException(e);
    }
}

Well, this line here results in a recursion, so you will see a StackOverflowError. I don’t know what class you are extending, but maybe you wanted to use super.getConnection() instead?

Implementing ConnectionProvider interface. So, super.getConnection() is not possible.

Can’t this be achieved with ServiceRegistry?
Do you see any issue with the implementation using ServiceRegistry?

Ah, it should have been provider.getConnection(), seems you pasted wrong code here. Anyway, take a look at this implementation which delegates to the underlying connection provider: https://github.com/hibernate/hibernate-orm/blob/master/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/ConnectionProviderDelegate.java

I think you should be able use a similar approach for unlocking the driver.

Hi Beikov,

Thanks for the suggestion. I have updated and refactored the getConnection() method (in delegate implementation) with the unlocking code for driver.

Back to original problem that the refactored implementation is not invoked for connection. No logs introduced in the method is available in out.

Stacktrace:

Dec 11, 2020 8:29:26 AM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate ORM core version 5.4.18.Final 
INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
Dec 11, 2020 8:29:28 AM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
Dec 11, 2020 8:29:28 AM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.PostgreSQL95Dialect
Dec 11, 2020 8:29:28 AM org.hibernate.engine.jdbc.spi.TypeInfo extractTypeInfo
WARN: HHH000362: Unable to retrieve type info result set : java.sql.SQLException: [PostgreSQL JDBC Driver]This driver is locked for use with embedded applications.
Dec 11, 2020 8:29:28 AM org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentImpl sequenceInformationList
ERROR: Could not fetch the SequenceInformation from the database
java.sql.SQLException: [PostgreSQL JDBC Driver]This driver is locked for use with embedded applications.
	at com.wm.dd.jdbc.postgresqlbase.ddcp.b(Unknown Source)
	at com.wm.dd.jdbc.postgresqlbase.ddcp.a(Unknown Source)
	at com.wm.dd.jdbc.postgresqlbase.ddco.b(Unknown Source)
	at com.wm.dd.jdbc.postgresqlbase.ddco.a(Unknown Source)
	at com.wm.dd.jdbc.postgresqlbase.BaseConnection.createStatement(Unknown Source)
	at com.wm.dd.jdbc.postgresqlbase.BaseConnection.createStatement(Unknown Source)
	at org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl.extractMetadata(SequenceInformationExtractorLegacyImpl.java:40)
	at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentImpl.sequenceInformationList(JdbcEnvironmentImpl.java:403)
	at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentImpl.<init>(JdbcEnvironmentImpl.java:268)
	at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:114)
	at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
	at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:101)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
	at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.injectServices(DefaultIdentifierGeneratorFactory.java:152)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.injectDependencies(AbstractServiceRegistryImpl.java:286)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:243)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
	at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:176)
	at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:118)
	at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:83)
	at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:473)
	at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:84)
	at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:689)
	at dev.venkat.jdbc.JDBCManager.<init>(JDBCManager.java:44)
	at dev.venkat.jdbc.JDBCManager.main(JDBCManager.java:55)

Dec 11, 2020 8:29:28 AM org.hibernate.engine.jdbc.spi.TypeInfo extractTypeInfo
WARN: HHH000362: Unable to retrieve type info result set : java.sql.SQLException: [PostgreSQL JDBC Driver]This driver is locked for use with embedded applications.

As you see in the following, it should be possible to pass the connection provider instance via the configuration map: https://github.com/hibernate/hibernate-orm/blob/cc600abf38afed99b4e9ce6f123f2e0582d6002a/hibernate-core/src/test/java/org/hibernate/test/timestamp/LocalDateCustomSessionLevelTimeZoneTest.java#L67

Hi Beikov,

It is not possible to pass the connection provider instance in settings as ConnectionProviderDelegate needs a delegate instance.

I’m not sure why the custom connection provider implementation has not been honored.
Any help on it would be great!

Apologize for the long delay.

As you can see in org.hibernate.testing.jdbc.ConnectionProviderDelegate#configure it will initialize the delegate on startup. What is the problem you are facing? Have you tried debugging into the configure method to see what is happening?