Java.Hibernate.Medium.Explain how MultiTenantConnectionProvider works and CurrentTenantIdentifierResolver works ?

Short Answer

  • MultiTenantConnectionProvider is the Hibernate SPI that provides connections specific to each tenant, e.g., different schemas or databases.
  • CurrentTenantIdentifierResolver tells Hibernate which tenant ID to use for the current request.

Together, they let Hibernate dynamically route connections and SQL statements to the correct tenant context.

🔎 Detailed Explanation

🔹 MultiTenantConnectionProvider
✅ It’s an interface you implement to supply JDBC connections appropriate for each tenant.
✅ Methods of interest:

  • getConnection(String tenantIdentifier) → returns a connection configured for the requested tenant.
  • releaseConnection(String tenantIdentifier, Connection connection) → cleans up when done.

✅ Hibernate calls your MultiTenantConnectionProvider whenever it needs a connection → your implementation decides how to get the right connection:

  • For SCHEMA strategy → reuse one DataSource, but set the schema with SET SCHEMA tenant_x.
  • For DATABASE strategy → open connections from different DataSources, one per tenant.

✅ Example skeleton:

public class SchemaMultiTenantConnectionProvider implements MultiTenantConnectionProvider {
    private final DataSource dataSource;

    public SchemaMultiTenantConnectionProvider(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    @Override
    public Connection getConnection(String tenantIdentifier) throws SQLException {
        Connection connection = dataSource.getConnection();
        connection.createStatement().execute("SET SCHEMA '" + tenantIdentifier + "'");
        return connection;
    }

    @Override
    public void releaseConnection(String tenantIdentifier, Connection connection) throws SQLException {
        connection.close();
    }
    
    // other required methods...
}

🔹 CurrentTenantIdentifierResolver
✅ Tells Hibernate which tenant identifier to use for the current request/session.
✅ It has a single important method:

String resolveCurrentTenantIdentifier();

✅ This is typically implemented by reading tenant information from:

  • HTTP request headers
  • ThreadLocal context
  • Security context

✅ Example skeleton:

public class HeaderTenantIdentifierResolver implements CurrentTenantIdentifierResolver {
    @Override
    public String resolveCurrentTenantIdentifier() {
        return TenantContext.getCurrentTenant(); // from ThreadLocal or request context
    }

    @Override
    public boolean validateExistingCurrentSessions() {
        return true; // allows reusing session if tenant ID doesn’t change
    }
}

🔹 How do they work together?
1️⃣ A user makes a request → you determine tenant ID (e.g., from HTTP header).
2️⃣ CurrentTenantIdentifierResolver returns the tenant ID to Hibernate.
3️⃣ Hibernate passes that tenant ID to MultiTenantConnectionProvider.getConnection(...).
4️⃣ Your provider returns the appropriate connection → either switching schema or connecting to the right DB.

✅ Hibernate then uses the returned connection for all operations in the current session.


🔹 Multi-tenancy strategies supported by Hibernate
SCHEMA → one database, multiple schemas → SET SCHEMA per tenant.
DATABASE → multiple databases → different DataSource or connection pools per tenant.
DISCRIMINATOR → one table with tenant_id column (simplest).


📌 Key Takeaways

CurrentTenantIdentifierResolver → identifies which tenant is active for the current session/request.
MultiTenantConnectionProvider → provides connections tied to that tenant.
✅ Together, they enable Hibernate’s multi-tenancy strategies, isolating tenant data at runtime.

This entry was posted in Без рубрики. Bookmark the permalink.

Leave a Reply

Your email address will not be published.