gpt4 book ai didi

java - Spring AbstractRoutingDataSource + Hibernate- Hbm2ddlSchemaUpdate 仅在默认数据库上执行

转载 作者:搜寻专家 更新时间:2023-10-30 23:02:14 24 4
gpt4 key购买 nike

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

(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 个数据库执行。

**稍后当我执行 rest URL 时

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

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

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

最佳答案

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

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

关于java - Spring AbstractRoutingDataSource + Hibernate- Hbm2ddlSchemaUpdate 仅在默认数据库上执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37273880/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com