This guide shows how to build
multi-tenant applications using
Spring Boot and
SAP HANA Express.
1. Define Tenant Context
Create a holder for the current tenant:
public class TenantContext {
private static final ThreadLocal<String> tenantId = new ThreadLocal<>();
public static void setTenantId(String id) {
tenantId.set(id);
}
public static String getTenantId() {
return tenantId.get();
}
public static void clear() {
tenantId.remove();
}
}
2. Add Tenant Interceptor
Extract tenant ID from the request header:
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import java.io.IOException;
public class TenantInterceptor implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
String tenantId = request.getHeader("X-Tenant-ID");
TenantContext.setTenantId(tenantId != null ? tenantId : "default");
try {
chain.doFilter(req, res);
} finally {
TenantContext.clear();
}
}
}
Register the filter in your config.
3. Configure Multi-Tenant Datasource
import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
public class TenantConnectionProvider implements MultiTenantConnectionProvider {
private final DataSource dataSource;
public TenantConnectionProvider(DataSource dataSource) {
this.dataSource = dataSource;
}
@Override
public Connection getConnection(String tenantId) throws SQLException {
Connection conn = dataSource.getConnection();
conn.setSchema(tenantId);
return conn;
}
@Override
public Connection getConnection() throws SQLException {
return getConnection(TenantContext.getTenantId());
}
}
Each tenant uses its own schema in SAP HANA Express.
4. Hibernate Multi-Tenant Configuration
import org.springframework.context.annotation.*;
import org.springframework.orm.jpa.*;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import javax.sql.DataSource;
@Configuration
public class HibernateConfig {
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
DataSource dataSource, TenantConnectionProvider connectionProvider) {
LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
emf.setDataSource(dataSource);
emf.setPackagesToScan("com.example.demo");
emf.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
emf.getJpaPropertyMap().put("hibernate.multiTenancy", "SCHEMA");
emf.getJpaPropertyMap().put("hibernate.multi_tenant_connection_provider", connectionProvider);
return emf;
}
}
5. Test Multi-Tenancy
- Create schemas in HANA:
CREATE SCHEMA tenant1;
CREATE SCHEMA tenant2;
- Insert different data in each schema.
- Call API with header
X-Tenant-ID: tenant1
or tenant2
to switch tenants.
image quote pre code