簡體   English   中英

基於模式 - 多租戶 - Spring 啟動

[英]Schema Based - Multitenant - Spring Boot

我正在嘗試創建基於簡約模式的 - 多租戶 - Spring 引導,但出現以下錯誤。 應用程序可以從GitHub https://github.com/ivoronline/spring_boot_db_multitenant下載

錯誤

Unable to instantiate specified multi-tenant connection provider [com.ivoronline.spring_boot_db_multitenant.config.TenantConnectionProvider]

應用程序.properties

#spring.jpa.properties.hibernate.multiTenancy = SCHEMA
spring.jpa.properties.hibernate.multiTenancy                     = SCHEMA
spring.jpa.properties.hibernate.multi_tenant_connection_provider = com.ivoronline.spring_boot_db_multitenant.config.TenantConnectionProvider
spring.jpa.properties.hibernate.tenant_identifier_resolver       = com.ivoronline.spring_boot_db_multitenant.config.TenantIdentifierResolver

# JPA / HIBERNATE
spring.jpa.hibernate.ddl-auto = create

DataSourceConfig.java

@Configuration
public class DataSourceConfig {

      @Bean
      public DataSource dataSource()   {
        DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
                          dataSourceBuilder.url("jdbc:postgresql://localhost:5432/multitenant");
                          dataSourceBuilder.username("postgres");
                          dataSourceBuilder.password("letmein");
                          dataSourceBuilder.driverClassName("org.postgresql.Driver");
        return            dataSourceBuilder.build();
      }
    
    }

TenantIdentifierResolver.java

@Component
public class TenantIdentifierResolver implements CurrentTenantIdentifierResolver {

  static final String DEFAULT_TENANT = "public";

  @Override
  public String resolveCurrentTenantIdentifier() {
    return "public";
  }

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

}

TenantConnectionProvider.java

@Component
public class TenantConnectionProvider implements MultiTenantConnectionProvider {

  private DataSource datasource;

  public TenantConnectionProvider(DataSource dataSource) {
    this.datasource = dataSource;
  }

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

  @Override
  public void releaseAnyConnection(Connection connection) throws SQLException {
    connection.close();
  }

  @Override
  public Connection getConnection(String tenantIdentifier) throws SQLException {
    final Connection connection = getAnyConnection();
    //connection.createStatement().execute(String.format("SET SCHEMA \"%s\";", tenantIdentifier));
    connection.createStatement().execute("SET Schema 'public'");
    return connection;
  }

  @Override
  public void releaseConnection(String tenantIdentifier, Connection connection) throws SQLException {
    //connection.createStatement().execute(String.format("SET SCHEMA \"%s\";", TenantIdentifierResolver.DEFAULT_TENANT));
    connection.createStatement().execute("SET Schema 'public'");
    releaseAnyConnection(connection);
  }

  @Override
  public boolean supportsAggressiveRelease() {
    return false;
  }

  @Override
  public boolean isUnwrappableAs(Class unwrapType) {
    return false;
  }

  @Override
  public <T> T unwrap(Class<T> unwrapType) {
    return null;
  }

}

Hibernate 期望屬性hibernate.multi_tenant_connection_provider定義已經初始化的 object 或 class 名稱,Hibernate 可以實例化。 在您的情況下, TenantConnectionProvider class 沒有默認構造函數,因此 Hibernate 失敗(此外,您期望TenantConnectionProvider是一個spring組件)。 通常有兩個選項來配置此類 Hibernate SPI:

  1. Hibernate 方式 - 使用ManagedBeanRegistry與 spring 上下文交互
public class TenantConnectionProvider implements MultiTenantConnectionProvider, ServiceRegistryAwareService {

    private ServiceRegistryImplementor serviceRegistry;
    
    // default constructor
    public TenantConnectionProvider() {
        super();
    }

    @Override
    public void injectServices(ServiceRegistryImplementor serviceRegistry) {
        this.serviceRegistry = serviceRegistry;
    }
    
    protected DataSource getDataSource() {
        return serviceRegistry.getService(ManagedBeanRegistry.class)
                .getBean(DataSource.class)
                .getBeanInstance();
    }
    
    ...

}
  1. spring-boot方式——在Java代碼中配置JPA屬性:
@Bean
public HibernatePropertiesCustomizer tenantConnectionProviderCustomizer(TenantConnectionProvider tenantConnectionProvider) {
    return hibernateProperties -> {
        hibernateProperties.put(AvailableSettings.MULTI_TENANT_CONNECTION_PROVIDER, tenantConnectionProvider);
    };
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM