hibernate/hibernate-orm · error · UnsupportedOperationException

ConnectionProvider does not support contextual credentials:

Error message

ConnectionProvider does not support contextual credentials: {} (use a different ConnectionProvider for credentials-based multitenancy)

What it means

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)).

Source

Thrown at hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/spi/ConnectionProvider.java:63

	 */
	Connection getConnection() throws SQLException;

	/**
	 * Obtains a connection for Hibernate use according to the underlying strategy of this provider,
	 * using the given credentials.
	 *
	 * @param user The database user
	 * @param password The database password
	 * @return The obtained JDBC connection
	 *
	 * @throws SQLException Indicates a problem opening a connection
	 * @throws org.hibernate.HibernateException Indicates a problem obtaining a connection.
	 *
	 * @since 7.3
	 */
	@Incubating
	default Connection getConnection(String user, String password) throws SQLException {
		throw new UnsupportedOperationException(
				"ConnectionProvider does not support contextual credentials: "
						+ getClass().getTypeName()
						+ " (use a different ConnectionProvider for credentials-based multitenancy)" );
	}

	/**
	 * Obtains a connection to a read-only replica for use according to the underlying
	 * strategy of this provider.
	 *
	 * @return The obtained JDBC connection
	 *
	 * @throws SQLException Indicates a problem opening a connection
	 * @throws org.hibernate.HibernateException Indicates a problem obtaining a connection.
	 *
	 * @implNote This default implementation simply calls {@link #getConnection()},
	 * which returns a connection to a writable replica. If this operation is overridden
	 * to return a connection to a distinct read-only replica, the matching operation
	 * {@link #closeReadOnlyConnection(Connection)} must also be overridden.

View on GitHub (pinned to fad1729dce)

Solutions

  1. Switch to a provider that overrides getConnection(String,String) - e.g. DataSourceConnectionProvider (delegates to DataSource.getConnection(user,password)) or your own subclass
  2. Override getConnection(String user, String password) in a custom ConnectionProvider to open connections with the tenant credentials
  3. If per-tenant credentials are not actually needed, invoke getConnection() without credentials so the default path is used
  4. Model tenancy by tenant id (DATABASE/TENANT identifier switching to different DataSources) instead of by username/password

Example fix

// before
Connection c = connectionProvider.getConnection(tenantUser, tenantPass); // UnsupportedOperationException

// after - use a provider that supports contextual credentials
DataSourceConnectionProvider p = new DataSourceConnectionProvider();
p.configure(Map.of(DATASOURCE, dataSource)); // DataSource.getConnection(user, pass) path
Connection c = p.getConnection(tenantUser, tenantPass);
Defensive patterns

Strategy: try-catch

Validate before calling

// check the provider actually overrides the default method before relying on it
Method m = provider.getClass().getMethod("getConnection", String.class, String.class);
boolean supportsCredentials = m.getDeclaringClass() != ConnectionProvider.class;
if ( !supportsCredentials ) {
    throw new IllegalStateException(provider.getClass() + " cannot open connections with contextual credentials");
}

Try / catch

try {
    return provider.getConnection(user, password);
} catch (UnsupportedOperationException e) {
    // provider has no contextual-credential support: open with configured credentials
    return provider.getConnection();
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/4797f2635f3db3da. Report an issue: GitHub.