Database/Schema在调用API时未切换。

huangapple go评论86阅读模式
英文:

Database/Schema is not being switched when API is called

问题

I am trying to implement hibernate multitenancy in my SpringBootWebApplication.

PROBLEM - tenant is being set in filter but when query is called Datasource is not being switched.
bad SQL grammar []; nested exception is org.postgresql.util.PSQLException: ERROR: relation "xyz" does not exist.

Here are the details

  • spring-boot-starter-parent -- 2.5.12

  • MyBatis for BE queries.

  • Hibernate for multi-tenancy.

  1. @Configuration
  2. @EnableTransactionManagement
  3. @EnableJpaRepositories(
  4. basePackages = {"com.xyz.*"}
  5. )
  6. public class HibernateConfig {
  7. @Autowired
  8. private JpaProperties jpaProperties;
  9. public HibernateConfig() {
  10. }
  11. @Bean
  12. JpaVendorAdapter jpaVendorAdapter() {
  13. return new HibernateJpaVendorAdapter();
  14. }
  15. @Bean(name = {"entityManagerFactory"})
  16. public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, MultiTenantConnectionProvider multiTenantConnectionProviderImpl, CurrentTenantIdentifierResolver currentTenantIdentifierResolverImpl){
  17. Map<String, Object> jpaPropertiesMap = new HashMap(this.jpaProperties.getProperties());
  18. jpaPropertiesMap.put("hibernate.multiTenancy", MultiTenancyStrategy.SCHEMA);
  19. jpaPropertiesMap.put("hibernate.multi_tenant_connection_provider", multiTenantConnectionProviderImpl);
  20. jpaPropertiesMap.put("hibernate.tenant_identifier_resolver", currentTenantIdentifierResolverImpl);
  21. jpaPropertiesMap.put("hibernate.format_sql", true);
  22. jpaPropertiesMap.put("hibernate.show_sql", true);
  23. LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
  24. em.setDataSource(dataSource);
  25. em.setJpaVendorAdapter(this.jpaVendorAdapter());
  26. em.setJpaPropertyMap(jpaPropertiesMap);
  27. em.setPackagesToScan(new String[]{"com.xyz.*"});
  28. return em;
  29. }
  30. }
  1. @Component
  2. public class DataSourceBasedMultiTenantConnectionProviderImpl extends AbstractDataSourceBasedMultiTenantConnectionProviderImpl {
  3. private static final long serialVersionUID = 1L;
  4. private static final String DEFAULT_TENANT_ID = "master";
  5. @Autowired
  6. private DataSource defaultDS;
  7. @Autowired
  8. private ApplicationContext context;
  9. private Map<String, DataSource> map = new HashMap();
  10. boolean init = false;
  11. public DataSourceBasedMultiTenantConnectionProviderImpl() {
  12. }
  13. @PostConstruct
  14. public void load() {
  15. this.map.put("master", this.defaultDS);
  16. }
  17. protected DataSource selectAnyDataSource() {
  18. return (DataSource)this.map.get("master");
  19. }
  20. protected DataSource selectDataSource(String tenantIdentifier) {
  21. if (!this.init) {
  22. this.init = true;
  23. TenantDataSource tenantDataSource = (TenantDataSource)this.context.getBean(TenantDataSource.class);
  24. this.map.putAll(tenantDataSource.getAll());
  25. }
  26. return this.map.get(tenantIdentifier) != null ? (DataSource)this.map.get(tenantIdentifier) : (DataSource)this.map.get("master");
  27. }
  28. }

The above Datasource provider is not being called.
Thanks in advance for your Help!!!

英文:

I am trying to implement hibernate multitenancy in my SpringBootWebApplication.

PROBLEM - tenant is being set in filter but when query is called Datasource is not being switched.
bad SQL grammar []; nested exception is org.postgresql.util.PSQLException: ERROR: relation "xyz" does not exist.

Here are the details

  • spring-boot-starter-parent -- 2.5.12

  • MyBatis for BE queries.

  • Hibernate for multi-tenancy.

  1. @Configuration
  2. @EnableTransactionManagement
  3. @EnableJpaRepositories(
  4. basePackages = {&quot;com.xyz.*&quot;}
  5. )
  6. public class HibernateConfig {
  7. @Autowired
  8. private JpaProperties jpaProperties;
  9. public HibernateConfig() {
  10. }
  11. @Bean
  12. JpaVendorAdapter jpaVendorAdapter() {
  13. return new HibernateJpaVendorAdapter();
  14. }
  15. @Bean(name = {&quot;entityManagerFactory&quot;})
  16. public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, MultiTenantConnectionProvider multiTenantConnectionProviderImpl, CurrentTenantIdentifierResolver currentTenantIdentifierResolverImpl){
  17. Map&lt;String, Object&gt; jpaPropertiesMap = new HashMap(this.jpaProperties.getProperties());
  18. jpaPropertiesMap.put(&quot;hibernate.multiTenancy&quot;, MultiTenancyStrategy.SCHEMA);
  19. jpaPropertiesMap.put(&quot;hibernate.multi_tenant_connection_provider&quot;, multiTenantConnectionProviderImpl);
  20. jpaPropertiesMap.put(&quot;hibernate.tenant_identifier_resolver&quot;, currentTenantIdentifierResolverImpl);
  21. jpaPropertiesMap.put(&quot;hibernate.format_sql&quot;, true);
  22. jpaPropertiesMap.put(&quot;hibernate.show_sql&quot;, true);
  23. LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
  24. em.setDataSource(dataSource);
  25. em.setJpaVendorAdapter(this.jpaVendorAdapter());
  26. em.setJpaPropertyMap(jpaPropertiesMap);
  27. em.setPackagesToScan(new String[]{&quot;com.xyz.*&quot;});
  28. return em;
  29. }
  30. }
  1. @Component
  2. public class DataSourceBasedMultiTenantConnectionProviderImpl extends AbstractDataSourceBasedMultiTenantConnectionProviderImpl {
  3. private static final long serialVersionUID = 1L;
  4. private static final String DEFAULT_TENANT_ID = &quot;master&quot;;
  5. @Autowired
  6. private DataSource defaultDS;
  7. @Autowired
  8. private ApplicationContext context;
  9. private Map&lt;String, DataSource&gt; map = new HashMap();
  10. boolean init = false;
  11. public DataSourceBasedMultiTenantConnectionProviderImpl() {
  12. }
  13. @PostConstruct
  14. public void load() {
  15. this.map.put(&quot;master&quot;, this.defaultDS);
  16. }
  17. protected DataSource selectAnyDataSource() {
  18. return (DataSource)this.map.get(&quot;master&quot;);
  19. }
  20. protected DataSource selectDataSource(String tenantIdentifier) {
  21. if (!this.init) {
  22. this.init = true;
  23. TenantDataSource tenantDataSource = (TenantDataSource)this.context.getBean(TenantDataSource.class);
  24. this.map.putAll(tenantDataSource.getAll());
  25. }
  26. return this.map.get(tenantIdentifier) != null ? (DataSource)this.map.get(tenantIdentifier) : (DataSource)this.map.get(&quot;master&quot;);
  27. }
  28. }

The above Datasource provider is not being called.
Thanks in advance for your Help!!!

答案1

得分: 0

我找到了问题。

我的项目正在使用MyBatis进行数据库查询。由于配置是通过Hibernate设置的,所以在触发查询时使用SpringDataJPA或Hibernate有助于切换数据库。

英文:

I have found the issue.

My project is using MyBatis for Database queries. Since the configuration is set via hibernate, so using SpringDataJPA or hibernate helped in switching the DB while triggering the query.

huangapple
  • 本文由 发表于 2023年5月25日 20:37:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/76332345.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定