【问题标题】:Spring AbstractRoutingDataSource + Hibernate- Hbm2ddlSchemaUpdate is executed only on default DBSpring AbstractRoutingDataSource + Hibernate- Hbm2ddlSchemaUpdate 仅在默认数据库上执行
【发布时间】:2016-09-13 10:06:36
【问题描述】:

我正在使用 SpringBoot,以及 Hibernate 作为持久性提供程序。 对于我的应用程序,我需要在 2 个 DB 之间动态选择。

(For simplicity sake, 
  domain : localhost:8080 ---> hem1 DB
  domain : 127.0.0.1:8080 ---> hem2 DB
)

以下是 AbstractRoutingDB 的实现

    public class MyRoutingDataSource extends AbstractRoutingDataSource{
        @Override
        protected Object determineCurrentLookupKey() {

        /*
         * this is derived from threadlocal set by filter for each web           
         * request
         */
             return SessionUtil.getDB(); 
        }
    }

以下是数据库配置:

  package com.hemant.basic.dataSource;

    import java.beans.PropertyVetoException;
    import java.util.HashMap;
    import java.util.Map;

    import javax.naming.ConfigurationException;
    import javax.sql.DataSource;

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;

    import com.mchange.v2.c3p0.ComboPooledDataSource;

    @Configuration
    public class DBConfig {

        @Bean(name = "dataSource")
        public DataSource dataSource() throws PropertyVetoException,
                ConfigurationException {
            MyRoutingDataSource routingDB = new MyRoutingDataSource();
            Map<Object, Object> targetDataSources = datasourceList();

// hem1 is the default target DB            
routingDB.setDefaultTargetDataSource(targetDataSources.get(1));
            routingDB.setTargetDataSources(targetDataSources);
            routingDB.afterPropertiesSet();
            return routingDB;
        }

        private Map<Object, Object> datasourceList() throws PropertyVetoException,
                ConfigurationException {
            final Map<Object, Object> datasources = new HashMap<Object, Object>();
            ComboPooledDataSource datasource = null;
            for (int id = 1; id <= 2; id++) {
                datasource = getDatasource(id);
                datasources.put(id, datasource);
            }
            return datasources;
        }

        private ComboPooledDataSource getDatasource(int id)
                throws PropertyVetoException, ConfigurationException {
            ComboPooledDataSource datasource = new ComboPooledDataSource();

            // set the connection pool properties
            datasource.setJdbcUrl("jdbc:postgresql://localhost/hem" + id);
            datasource.setUser("hemant");
            datasource.setPassword("");
            datasource.setDriverClass("org.postgresql.Driver");
            datasource.setMaxPoolSize(30);
            datasource.setInitialPoolSize(10);
            datasource.setMinPoolSize(10);

            return datasource;
        }
    }

application.properties 中还有以下设置,以便自动模式更新处于开启状态。

# Hibernate ddl auto (create, create-drop, update)
spring.jpa.hibernate.ddl-auto = update

问题:当我启动应用程序时, hbm2ddl 架构更新仅在 hem1 (defaultTargetDb) 上执行,而不在其他目标数据库上执行

以下是启动日志的一部分

[main] org.hibernate.tool.hbm2ddl.SchemaUpdate  : HHH000228: Running hbm2ddl schema update
[main] org.hibernate.tool.hbm2ddl.SchemaUpdate  : HHH000102: Fetching database metadata
[main] org.hibernate.tool.hbm2ddl.SchemaUpdate  : HHH000396: Updating schema
[main] java.sql.DatabaseMetaData                : HHH000262: Table not found: users
[main] java.sql.DatabaseMetaData                : HHH000262: Table not found: users
[main] java.sql.DatabaseMetaData                : HHH000262: Table not found: users
[main] org.hibernate.tool.hbm2ddl.SchemaUpdate  : HHH000232: Schema update complete`enter code here`

这仅针对 1 DB 执行。

**稍后当我执行 rest URL 时说

GET localhost:8080/users - 成功获取已更新的 DB hem1 的结果。

但是当访问 GET 127.0.0.1:8080/users 时,由于 schema 没有更新/创建,导致 SQL Exception**

我们如何确保在 AbstractRoutingDataSource 的所有目标数据库上执行“hbm2ddl 架构更新”

【问题讨论】:

标签: java spring hibernate spring-mvc spring-data-jpa


【解决方案1】:

据我所知,您无法在多租户环境中设置模式导出。当您定义多租户环境时,默认情况下,它只会连接到默认数据库以获取连接。这就是为什么您只能在一个数据库中创建。它不会访问所有要创建的数据库/模式,因为它彼此不知道。

保存一个 SQL 数据库创建文件并在每次创建新租户时执行它。我认为您可以在需要时使用 Spring PersistenceContext 为您创建它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-10-26
    • 1970-01-01
    • 2018-12-10
    • 1970-01-01
    • 1970-01-01
    • 2011-11-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多