我有一个应用程序,它需要连接到几个不同的架构,但都需要连接到同一类型(ORACLE)。决定哪个模式来自UI。
如果用户选择了schema1,则实体应保留在Schema1中;如果选择其他,则实体应位于所选的其他模式中。
我正在使用带有依赖项“ spring-boot-starter-data-jpa”的Spring Boot + Hibernate
我已经创建了如下所示的数据源类,以便可以在调用数据层之前每次更改数据源对象中的“ schemaName”。
@Component public class SchemaDatasource extends AbstractDataSource { private String schemaName; @Autowired private DSManager dsm; public void setSchemaName(String schemaName) { this.schemaName = schemaName; } @Override public Connection getConnection() throws SQLException { if (schemaName!= null) return dsm.getConnection(schemaName); else return null; } @Override public Connection getConnection(String username, String password) throws SQLException { if (schemaName!= null) return dsm.getConnection(schemaName); else return null; } }
我的问题是在启动过程中,“ HibernateJpaAutoConfiguration”尝试创建sessionfactory。在创建过程中,它尝试检查与数据源的连接,但是由于schemaName在启动时为null,因此我的SchemaDatasource返回的null连接导致应用程序引导失败。
有没有办法解决这个问题。我期望与SessionFactory类似,在hibernate状态下没有选项。
同样在RoutingDatasource的情况下,我必须设置defaultDatasource。
Spring boot version: 1.5.9.RELEASE
这是我对DataSource的实现
public class DataSourceManager implements DataSource { private Map<String, DataSource> dataSources = new HashMap<>(); private DataSource dataSource; public DataSourceManager() { } public DataSourceManager(DataSource dataSource) { this.dataSource = dataSource; } public void add(String name, DataSource dataSource) { dataSources.put(name, dataSource); } public void switchDataSource(String name) { dataSource = dataSources.get(name); } @Override public PrintWriter getLogWriter() throws SQLException { return dataSource.getLogWriter(); } @Override public void setLogWriter(PrintWriter out) throws SQLException { dataSource.setLogWriter(out); } @Override public void setLoginTimeout(int seconds) throws SQLException { dataSource.setLoginTimeout(seconds); } @Override public int getLoginTimeout() throws SQLException { return dataSource.getLoginTimeout(); } @Override public Logger getParentLogger() throws SQLFeatureNotSupportedException { return dataSource.getParentLogger(); } @Override public <T> T unwrap(Class<T> iface) throws SQLException { return dataSource.unwrap(iface); } @Override public boolean isWrapperFor(Class<?> iface) throws SQLException { return dataSource.isWrapperFor(iface); } @Override public Connection getConnection() throws SQLException { return dataSource.getConnection(); } @Override public Connection getConnection(String username, String password) throws SQLException { return dataSource.getConnection(username, password); } }
这是我的配置
@Configuration public class DataSourceConfig { @Autowired private Environment env; public DataSource makeDataSource(String name) { return DataSourceBuilder.create() .driverClassName(env.getProperty("spring.datasource." + name + ".driver-class-name")) .url(env.getProperty("spring.datasource." + name + ".url")).build(); } @Bean public DataSource dataSource() { DataSourceManager dataSourceManager = new DataSourceManager(); dataSourceManager.add("test1", makeDataSource("test1")); dataSourceManager.add("test2", makeDataSource("test2")); dataSourceManager.switchDataSource("test1"); return dataSourceManager; } }
这是application.yml
spring: jpa: hibernate: ddl-auto: create properties: hibernate: dialect: org.hibernate.dialect.H2Dialect datasource: test1: name: test2 url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE driver-class-name: org.h2.Driver username: h2 password: h2 test2: name: test1 url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE driver-class-name: org.h2.Driver username: h2 password: h2