MrJazsohanisharma

Shared Schema Multitenancy in Hibernate

Blog ads

Shared Schema Multitenancy in Hibernate 6: A Practical Guide

1. Introduction

Multi-tenancy lets a single application serve multiple clients (tenants) while keeping data isolated. In shared schema multitenancy, all tenants share the same database schema but use a discriminator column or row-level filtering to separate data. Hibernate 6 simplifies this approach, eliminating older configurations like MultiTenancyStrategy and introducing streamlined setups.

Shared Schema Multitenancy in Hibernate


2. Usages

  • SaaS Applications: Manage customer data securely in a single database.
  • Regulatory Compliance: Isolate sensitive data without separate schemas.
  • Cost Efficiency: Reduce infrastructure costs compared to separate databases per tenant.
  • Scalability: Add tenants without schema duplication.

3. Code Example

Step 1: Define Tenant Resolver

@Component  
public class TenantIdentifierResolver implements CurrentTenantIdentifierResolver {  
    @Override  
    public String resolveCurrentTenantIdentifier() {  
        return Optional.ofNullable(TenantContext.getCurrentTenant())  
                .orElse("default_tenant");  
    }  

    @Override  
    public boolean validateExistingCurrentSessions() {  
        return true;  
    }  
}

Step 2: Configure Connection Provider

@Component  
public class SchemaConnectionProvider implements MultiTenantConnectionProvider {  
    @Autowired  
    private DataSource dataSource;  

    @Override  
    public Connection getAnyConnection() throws SQLException {  
        return dataSource.getConnection();  
    }  

    @Override  
    public Connection getConnection(String tenantId) throws SQLException {  
        Connection connection = getAnyConnection();  
        connection.setSchema(tenantId); // Switch schema dynamically  
        return connection;  
    }  

    @Override  
    public void releaseConnection(String tenantId, Connection connection) throws SQLException {  
        connection.setSchema("public"); // Reset to default schema  
        connection.close();  
    }  
}

Step 3: Enable Multi-tenancy in Hibernate

@Configuration  
public class HibernateConfig {  
    @Bean  
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(  
            DataSource dataSource,  
            MultiTenantConnectionProvider connectionProvider,  
            CurrentTenantIdentifierResolver tenantResolver) {  

        Map<String, Object> properties = new HashMap<>();  
        properties.put("hibernate.multi_tenant_connection_provider", connectionProvider);  
        properties.put("hibernate.tenant_identifier_resolver", tenantResolver);  

        return new EntityManagerFactoryBuilder(new HibernateJpaVendorAdapter())  
                .dataSource(dataSource)  
                .packages("com.example.model")  
                .properties(properties)  
                .build();  
    }  
}

4. Explanation

  • Tenant Resolver: Identifies the current tenant (e.g., from HTTP headers or JWT claims).
  • Connection Provider: Switches schemas at runtime using connection.setSchema().
  • Schema Isolation: Each tenant's data resides in a separate schema but within the same physical database.

5. Best Practices

  • ThreadLocal Storage: Store tenant IDs in ThreadLocal to avoid leaks across requests.
  • Schema Validation: Ensure schemas exist before switching (e.g., via Liquibase/Flyway).
  • Caching: Use tenant-specific caches to prevent cross-tenant data leaks.
  • Connection Pooling: Configure separate pools per tenant for high throughput.

6. Conclusion

Hibernate 6's shared schema multitenancy simplifies tenant isolation without complex infrastructure. By dynamically switching schemas and resolving tenants per request, you can build scalable SaaS applications efficiently.

ads

Previous Post Next Post