spring - 手动更改 Multi-Tenancy session

标签 spring hibernate spring-boot spring-data-jpa

我需要创建一个 Multi-Tenancy 应用程序,能够在 java 代码内的架构之间切换(不是基于用户请求)。

我读过文章: https://fizzylogic.nl/2016/01/24/make-your-spring-boot-application-multi-tenant-aware-in-2-steps/ http://www.greggbolinger.com/tenant-per-schema-with-spring-boot/ 当架构在 Rest-request 中传递时,解决方案工作正常。

但是我需要实现以下逻辑:

public void compare(String originalSchema, String secondSchema){
    TenantContext.setCurrentTenant(originalSchema);
    List<MyObject> originalData = myRepository.findData();

    TenantContext.setCurrentTenant(secondSchema);
    List<MyObject> migratedData = myRepository.findData();
}

重点是,当我手动设置 TenenantContext 时,连接没有切换。 MultiTenantConnectionProviderImpl.getConnection 仅在第一次调用我的存储库时调用。

 @Component
 public class MultiTenantConnectionProviderImpl implements  MultiTenantConnectionProvider {

     @Override
     public Connection getConnection(String tenantIdentifier) throws SQLException {
          final Connection connection = getAnyConnection();
          try {
               connection.createStatement().execute( "ALTER SESSION SET CURRENT_SCHEMA = " + tenantIdentifier );
          }
          catch ( SQLException e ) {
              throw new HibernateException(
      "Could not alter JDBC connection to specified schema [" + tenantIdentifier + "]",e);
          }
          return connection;
    }
 }

是否可以强制切换 session ?

最佳答案

找到了硬编码的解决方案。

@Service
public class DatabaseSessionManager {

    @PersistenceUnit
    private EntityManagerFactory entityManagerFactory;

    public void bindSession() {
        if (!TransactionSynchronizationManager.hasResource(entityManagerFactory)) {
            EntityManager entityManager = entityManagerFactory.createEntityManager();
            TransactionSynchronizationManager.bindResource(entityManagerFactory, new EntityManagerHolder(entityManager));
        }
    }

    public void unbindSession() {
        EntityManagerHolder emHolder = (EntityManagerHolder) TransactionSynchronizationManager
            .unbindResource(entityManagerFactory);
        EntityManagerFactoryUtils.closeEntityManager(emHolder.getEntityManager());
    }
}

每个 block ,在新的tenantContext中加载数据应该执行以下操作:

    databaseSessionManager.unbindSession();
    TenantContext.setCurrentTenant(schema);
    databaseSessionManager.bindSession();
    //execute selects

关于spring - 手动更改 Multi-Tenancy session ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46847059/

相关文章:

java - Log4j 似乎不适用于 Spring Boot

java - Hibernate 5 隐式策略和唯一键

spring-boot - 如何在@SpringBootApplication测试中使用@Configuration排除类

spring-boot - Spring启动登录mysql数据库

mysql - 如何使用 Spring Boot 在 MYSQL 数据库中导入 .sql 文件?

java - 如何从 RestTemplate 读取响应 header ?

java - Junit 测试单独通过,而不是分组通过

Java Spring REST Get 工作得很好,但是在发布 json 时出现 404 错误

java - Hibernate 继承 - 获取父类(super class)实例并转换为子类

java - 在 hql 查询或条件中将字符串列转换为 int