【问题标题】:Override entityManager factories mapping at conditionally at runtime在运行时有条件地覆盖 entityManager 工厂映射
【发布时间】:2021-08-03 08:05:01
【问题描述】:

我有一个使用AbstractRoutingDataSource 实现的多租户/数据库应用程序。一些 DB 的架构略有不同,并且在某些表中缺少一些列(这是静态的,并且每个 DB 都知道)。如果数据库没有列,我不想为每个数据库架构复制所有存储库和实体,我只想将丢失的列标记为瞬态(但如果列可用,仍保存所有信息)。

我能够使用基于 XML 的映射文件覆盖实体管理器工厂中基于注释的映射,我可以为所有可能的模式创建该映射文件。我的想法是使用适当的 XML 映射覆盖为每个租户创建一个实体管理器工厂。理想情况下,在租户的第一个请求中,它将实例化实体管理器工厂,然后检查要应用的映射覆盖。伪代码:

@Configuration
@EnableTransactionManagement
class JPAconfig {

  @Bean
  public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource myAbstractRoutingDataSource, TenantService tenantService) {
    final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
    em.setDataSource(myAbstractRoutingDataSource);
    em.setPackagesToScan("myPackagesToScan");
    final JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    em.setJpaVendorAdapter(vendorAdapter);
    em.setJpaProperties(additionalProperties());
    String schemaVer = env.getProperty("db.schema.version");

    // At runtime based on the tenant, override annotation based mappings
    em.setMappingResources(tenantService.getMappingsForTenant());
    
    return em;
  }
}

不幸的是,LocalContainerEntityManagerFactoryBean 是一个工厂 bean,似乎只允许单例或原型范围。也可以在编译时定义所有可能的 LocalContainerEntityManagerFactoryBean bean,并在运行时根据租户以某种方式选择正确的工厂。

【问题讨论】:

    标签: spring spring-boot spring-data-jpa


    【解决方案1】:

    更改您的休眠属性/配置后尝试重新加载应用程序上下文:

    ApplicationContextProvider.getApplicationContext().refresh();
    

    参考:Spring Hibernate: reload entity mappings

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-28
      • 2021-06-10
      • 1970-01-01
      • 2012-09-28
      • 2018-09-01
      • 2021-01-26
      • 1970-01-01
      • 2012-02-20
      相关资源
      最近更新 更多