{"record":{"id":"4797f2635f3db3da","repo":"hibernate/hibernate-orm","slug":"connectionprovider-does-not-support-contextual-cre","errorCode":null,"errorMessage":"ConnectionProvider does not support contextual credentials: {} (use a different ConnectionProvider for credentials-based multitenancy)","messagePattern":"ConnectionProvider does not support contextual credentials: (.+?) \\(use a different ConnectionProvider for credentials-based multitenancy\\)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/spi/ConnectionProvider.java","lineNumber":63,"sourceCode":"\t */\n\tConnection getConnection() throws SQLException;\n\n\t/**\n\t * Obtains a connection for Hibernate use according to the underlying strategy of this provider,\n\t * using the given credentials.\n\t *\n\t * @param user The database user\n\t * @param password The database password\n\t * @return The obtained JDBC connection\n\t *\n\t * @throws SQLException Indicates a problem opening a connection\n\t * @throws org.hibernate.HibernateException Indicates a problem obtaining a connection.\n\t *\n\t * @since 7.3\n\t */\n\t@Incubating\n\tdefault Connection getConnection(String user, String password) throws SQLException {\n\t\tthrow new UnsupportedOperationException(\n\t\t\t\t\"ConnectionProvider does not support contextual credentials: \"\n\t\t\t\t\t\t+ getClass().getTypeName()\n\t\t\t\t\t\t+ \" (use a different ConnectionProvider for credentials-based multitenancy)\" );\n\t}\n\n\t/**\n\t * Obtains a connection to a read-only replica for use according to the underlying\n\t * strategy of this provider.\n\t *\n\t * @return The obtained JDBC connection\n\t *\n\t * @throws SQLException Indicates a problem opening a connection\n\t * @throws org.hibernate.HibernateException Indicates a problem obtaining a connection.\n\t *\n\t * @implNote This default implementation simply calls {@link #getConnection()},\n\t * which returns a connection to a writable replica. If this operation is overridden\n\t * to return a connection to a distinct read-only replica, the matching operation\n\t * {@link #closeReadOnlyConnection(Connection)} must also be overridden.","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/spi/ConnectionProvider.java#L45-L81","documentation":"ConnectionProvider.getConnection(String user, String password) is a new incubating method (Hibernate 7.3) enabling credentials-based multitenancy, where each tenant connects with its own username/password. The default method body throws UnsupportedOperationException because a plain ConnectionProvider cannot open connections with caller-supplied contextual credentials; only providers that override the method support it (e.g. DataSourceConnectionProvider, which delegates to DataSource.getConnection(user, password)).","triggerScenarios":"Calling connectionProvider.getConnection(user, password) on a provider that does not override the default method - e.g. DriverManagerConnectionProviderImpl or a pooled/JNDI provider - typically triggered indirectly by Hibernate's tenant-credentials machinery (CurrentTenantIdentifierResolver + tenant credentials mapping) when the configured provider lacks contextual-credential support.","commonSituations":"Adopting Hibernate 7.3 credentials-based multitenancy while keeping a connection provider that ignores credentials; passing a tenant-credentials mapper in configuration but forgetting to switch the ConnectionProvider; calling the incubating API directly on an arbitrary provider.","solutions":["Switch to a provider that overrides getConnection(String,String) - e.g. DataSourceConnectionProvider (delegates to DataSource.getConnection(user,password)) or your own subclass","Override getConnection(String user, String password) in a custom ConnectionProvider to open connections with the tenant credentials","If per-tenant credentials are not actually needed, invoke getConnection() without credentials so the default path is used","Model tenancy by tenant id (DATABASE/TENANT identifier switching to different DataSources) instead of by username/password"],"exampleFix":"// before\nConnection c = connectionProvider.getConnection(tenantUser, tenantPass); // UnsupportedOperationException\n\n// after - use a provider that supports contextual credentials\nDataSourceConnectionProvider p = new DataSourceConnectionProvider();\np.configure(Map.of(DATASOURCE, dataSource)); // DataSource.getConnection(user, pass) path\nConnection c = p.getConnection(tenantUser, tenantPass);","handlingStrategy":"try-catch","validationCode":"// check the provider actually overrides the default method before relying on it\nMethod m = provider.getClass().getMethod(\"getConnection\", String.class, String.class);\nboolean supportsCredentials = m.getDeclaringClass() != ConnectionProvider.class;\nif ( !supportsCredentials ) {\n    throw new IllegalStateException(provider.getClass() + \" cannot open connections with contextual credentials\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    return provider.getConnection(user, password);\n} catch (UnsupportedOperationException e) {\n    // provider has no contextual-credential support: open with configured credentials\n    return provider.getConnection();\n}","preventionTips":["When adopting credentials-based multitenancy, verify your ConnectionProvider implements getConnection(String,String) at startup","Treat the 7.3 credentials API as incubating: wrap its use behind one integration point so the provider can be swapped easily"],"tags":["hibernate","multitenancy","credentials","jdbc","incubating","unsupported-operation"],"backgroundTag":"provider-capability-not-supported","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}