Spring DataSourceContextHolder.setTargetDataSource()不工作
我在spring boot项目中有一个bootstrap.yml文件,其中包含一些DB数据源。我正在使用Spring DataSourceContextHolder.setTargetDataSource()不工作,spring,spring-boot,spring-data-jpa,lazy-initialization,Spring,Spring Boot,Spring Data Jpa,Lazy Initialization,我在spring boot项目中有一个bootstrap.yml文件,其中包含一些DB数据源。我正在使用DataSourceContextHolder.setTargetDataSource(“Datasource”)来更改数据源连接,以从其他数据库模式获取信息,但spring没有更改数据源,而是继续使用最后一个连接到的用户。我尝试使用open in view=true,但现在我们有了lazyInitException,所以我非常阻塞和困惑。有什么办法解决这个问题吗 这是我用来访问数据库信息的方
DataSourceContextHolder.setTargetDataSource(“Datasource”)
来更改数据源连接,以从其他数据库模式获取信息,但spring没有更改数据源,而是继续使用最后一个连接到的用户。我尝试使用open in view=true,但现在我们有了lazyInitException,所以我非常阻塞和困惑。有什么办法解决这个问题吗
这是我用来访问数据库信息的方法,在我的一个类中:
public Contract getAccount(String cdisoloc, String accountId) {
DataSourceContextHolder.setTargetDataSource(cdisoloc);
Optional<Contract> result = contractJpaRepository.findById(AccountUtils.mapAccountIdToPk(accountId));
return result.orElseThrow(() ->
new NotFoundException("Account " + accountId + " not found.", HttpStatus.NOT_FOUND, ErrorConstants.ERROR_NO_DATA_FOUND));
}
这是DataSourceContextHolder类:
package com.example.fce.bas.database;
public final class DataSourceContextHolder {
private DataSourceContextHolder() {
}
private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<String>();
public static void setTargetDataSource(String targetDataSource) {
CONTEXT_HOLDER.set(targetDataSource);
}
public static String getTargetDataSource() {
return (String) CONTEXT_HOLDER.get();
}
public static void resetDefaultDataSource() {
CONTEXT_HOLDER.remove();
}
}
这是DataSourceConfiguration类:
package com.example.fce.bas.database;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import java.util.HashMap;
@Data
@Configuration
public class DataSourceConfiguration {
@Bean
public DataSourceServices service(HashMap<String, DataSourceServices.DataSourceObject> cupsServices) {
return new DataSourceServices(cupsServices);
}
@Bean
@Primary
@ConfigurationProperties("vcap.services")
public HashMap<String, DataSourceServices.DataSourceObject> getCUPS() {
return new HashMap<>();
}
}
package com.example.fce.bas.database;
导入龙目数据;
导入org.springframework.boot.context.properties.ConfigurationProperties;
导入org.springframework.context.annotation.Bean;
导入org.springframework.context.annotation.Configuration;
导入org.springframework.context.annotation.Primary;
导入java.util.HashMap;
@资料
@配置
公共类数据源配置{
@豆子
公共数据源服务(HashMap cupsServices){
返回新的数据源服务(cupsServices);
}
@豆子
@初级的
@配置属性(“vcap.services”)
公共HashMap getCUPS(){
返回新的HashMap();
}
}
这是DataSourceServices类:
package com.example.fce.bas.database;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.springframework.stereotype.Component;
import java.util.HashMap;
@Data
@AllArgsConstructor
public class DataSourceServices {
private HashMap<String, DataSourceObject> dataSourceServices;
@Data
@Component
public static class DataSourceObject {
private DataSourceCredentials credentials;
@SuppressWarnings("checkstyle:membername")
private String syslog_drain_url;
@SuppressWarnings("checkstyle:membername")
private Object volume_mounts;
private String label;
private String name;
}
@Component
@Data
public static class DataSourceCredentials {
private String type;
private String as400Url;
private String jdbcUrl;
private String username;
private String password;
private String driverClassName;
private String connectionTestQuery;
private String location;
private int maximumPoolSize;
private int minimumIdle;
private long idleTimeout;
private long maxLifetime;
}
}
package com.example.fce.bas.database;
导入lombok.allargsconstuctor;
导入龙目数据;
导入org.springframework.stereotype.Component;
导入java.util.HashMap;
@资料
@AllArgsConstructor
公共类数据源服务{
私有HashMap数据源服务;
@资料
@组成部分
公共静态类DataSourceObject{
私有数据源机密凭证;
@SuppressWarnings(“checkstyle:membername”)
私有字符串syslog\u drain\u url;
@SuppressWarnings(“checkstyle:membername”)
私有对象卷装载;
私有字符串标签;
私有字符串名称;
}
@组成部分
@资料
公共静态类数据源目录{
私有字符串类型;
私有字符串as400Url;
私有字符串jdbcUrl;
私有字符串用户名;
私有字符串密码;
私有字符串驱动器rclassname;
私有字符串connectionTestQuery;
私有字符串位置;
私有int-maximumPoolSize;
私家车;
私人长期闲置;
私人长寿命;
}
}
最后,这是数据库配置:
package com.example.fce.bas.database;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ibm.as400.access.AS400;
import com.ibm.as400.access.AS400SecurityException;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.util.StringUtils;
import javax.sql.DataSource;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class DatabaseConfiguration {
private final DataSourceServices cups;
@Autowired
public DatabaseConfiguration(DataSourceServices cups) {
this.cups = cups;
}
@Bean
@Primary
public DataSource dataSource() {
return getDataSources(this.cups);
}
@Bean
public HashMap<String, AS400> as400() {
return getAs400List(this.cups);
}
private DataSource getDataSources(DataSourceServices dataSourceServices) {
final DataSource[] defaultDatasource = {null};
DataSourceRouter routingDataSource = null;
Map<Object, Object> targetDataSources = new HashMap<>();
if (dataSourceServices.getDataSourceServices() != null) {
routingDataSource = new DataSourceRouter();
dataSourceServices.getDataSourceServices().keySet().forEach(k -> {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
DataSourceServices.DataSourceObject dataSourceObject = mapper.convertValue(
cups.getDataSourceServices().get(k),
DataSourceServices.DataSourceObject.class);
if (dataSourceObject.getLabel().equals("user-provided")
&& dataSourceObject.getCredentials().getType().equals("datasource")) {
String url = dataSourceObject.getCredentials().getJdbcUrl();
String user = dataSourceObject.getCredentials().getUsername();
String password = dataSourceObject.getCredentials().getPassword();
String driverClassName = dataSourceObject.getCredentials().getDriverClassName();
String connectionTestQuery = dataSourceObject.getCredentials().getConnectionTestQuery();
String location = dataSourceObject.getCredentials().getLocation();
int maximumPoolSize = dataSourceObject.getCredentials().getMaximumPoolSize();
int minimumIdle = dataSourceObject.getCredentials().getMinimumIdle();
long idleTimeout = dataSourceObject.getCredentials().getIdleTimeout();
long maxLifetime = dataSourceObject.getCredentials().getMaxLifetime();
defaultDatasource[0] = createDataSource(url, user, password, driverClassName, connectionTestQuery,
maximumPoolSize, minimumIdle, idleTimeout, maxLifetime);
targetDataSources.put(location, createDataSource(url, user, password, driverClassName, connectionTestQuery,
maximumPoolSize, minimumIdle, idleTimeout, maxLifetime));
}
});
routingDataSource.setTargetDataSources(targetDataSources);
routingDataSource.setDefaultTargetDataSource(defaultDatasource[0]);
}
return routingDataSource;
}
private HashMap<String, AS400> getAs400List(DataSourceServices dataSourceServices) {
HashMap<String, AS400> targetAS400 = new HashMap<>();
if (dataSourceServices.getDataSourceServices() != null) {
dataSourceServices.getDataSourceServices().keySet().forEach(k -> {
DataSourceServices.DataSourceObject dataSourceObject = getDataSourceObject(k);
if (dataSourceObject.getLabel().equals("user-provided") && dataSourceObject.getCredentials().getType().equals("datasource")) {
String url = dataSourceObject.getCredentials().getAs400Url();
String user = dataSourceObject.getCredentials().getUsername();
String password = dataSourceObject.getCredentials().getPassword();
String location = dataSourceObject.getCredentials().getLocation();
targetAS400.put(location, createAS400(url, user, password));
}
});
}
return targetAS400;
}
private DataSource createDataSource(String dataSourceUrl,
String dataSourceUser,
String dataSourcePassword,
String dataSourceDriverClassName,
String dataSourceConnectionTestQuery,
int maximumPoolSize,
int minimumIdle,
long idleTimeout,
long maxLifetime) {
String dataSourceUrlOrNull = stringOrNull(dataSourceUrl);
if (dataSourceUrlOrNull == null) {
return null;
}
HikariDataSource ds = new HikariDataSource();
ds.setJdbcUrl(dataSourceUrlOrNull);
ds.setUsername(stringOrNull(dataSourceUser));
ds.setPassword(stringOrNull(dataSourcePassword));
ds.setDriverClassName(stringOrNull(dataSourceDriverClassName));
ds.setConnectionTestQuery(stringOrNull(dataSourceConnectionTestQuery));
ds.setMaximumPoolSize(maximumPoolSize);
ds.setMinimumIdle(minimumIdle);
ds.setIdleTimeout(idleTimeout);
ds.setMaxLifetime(maxLifetime);
return ds;
}
private AS400 createAS400(String dataSourceUrl,
String dataSourceUser,
String dataSourcePassword) {
AS400 as400 = new AS400(dataSourceUrl, dataSourceUser, dataSourcePassword);
try {
as400.validateSignon(dataSourceUser, dataSourcePassword);
System.out.println("AS400 Sign on validated for " + dataSourceUser + " in " + dataSourceUrl);
} catch (AS400SecurityException | IOException e) {
e.printStackTrace();
}
return as400;
}
private DataSourceServices.DataSourceObject getDataSourceObject(String k) {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return mapper.convertValue(cups.getDataSourceServices().get(k), DataSourceServices.DataSourceObject.class);
}
private String stringOrNull(String value) {
return StringUtils.isEmpty(value) ? null : value;
}
}
package com.example.fce.bas.database;
导入com.fasterxml.jackson.databind.DeserializationFeature;
导入com.fasterxml.jackson.databind.ObjectMapper;
导入com.ibm.as400.access.as400;
导入com.ibm.as400.access.AS400SecurityException;
导入com.zaxxer.hikari.HikariDataSource;
导入org.springframework.beans.factory.annotation.Autowired;
导入org.springframework.context.annotation.Bean;
导入org.springframework.context.annotation.Configuration;
导入org.springframework.context.annotation.Primary;
导入org.springframework.util.StringUtils;
导入javax.sql.DataSource;
导入java.io.IOException;
导入java.util.HashMap;
导入java.util.Map;
@配置
公共类数据库配置{
私有最终数据源服务cups;
@自动连线
公共数据库配置(数据源服务cups){
这个。杯子=杯子;
}
@豆子
@初级的
公共数据源数据源(){
返回getDataSources(this.cups);
}
@豆子
公共HashMap as400(){
返回getAs400List(this.cups);
}
私有数据源getDataSources(数据源服务数据源服务){
最终数据源[]defaultDatasource={null};
DataSourceOuter routingDataSource=null;
Map targetDataSources=new HashMap();
if(dataSourceServices.getDataSourceServices()!=null){
routingDataSource=新数据源外部();
dataSourceServices.getDataSourceServices().keySet().forEach(k->{
ObjectMapper mapper=新的ObjectMapper();
configure(在未知属性上反序列化feature.FAIL,false);
DataSourceServices.DataSourceObject DataSourceObject=mapper.convertValue(
cups.getDataSourceServices().get(k),
DataSourceServices.DataSourceObject.class);
if(dataSourceObject.getLabel().equals(“用户提供”)
&&dataSourceObject.getCredentials().getType().equals(“数据源”)){
字符串url=dataSourceObject.getCredentials().getJdbcUrl();
字符串user=dataSourceObject.getCredentials().getUsername();
字符串密码=dataSourceObject.getCredentials().getPassword();
String driverClassName=dataSourceObject.getCredentials().getDriverClassName();
String connectionTestQuery=dataSourceObject.getCredentials().getConnectionTestQuery();
字符串位置=dataSourceObject.getCredentials().getLocation();
int maximumPoolSize=dataSourceObject.getCredentials().getMaximumPoolSize();
int minimumIdle=dataSourceObject.getCredentials().getMinimumIdle();
long idleTimeout=dataSourceObject.getCredentials().getIdleTimeout();
long maxLifetime=dataSourceObject.getCredentials().getMaxLifetime();
defaultDatasource[0]=createDataSource(url、用户、密码、driverClassName、connectionTestQuery、,
maximumPoolSize、minimumIdle、idleTimeout、maxLifetime);
targetDataSources.put(位置、createDataSource(url、用户、密码、driverClassName、connectionTestQuery、,
maximumPoolSize、minimumIdle、idleTimeout、maxLifetime);
}
package com.example.fce.bas.database;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import java.util.HashMap;
@Data
@Configuration
public class DataSourceConfiguration {
@Bean
public DataSourceServices service(HashMap<String, DataSourceServices.DataSourceObject> cupsServices) {
return new DataSourceServices(cupsServices);
}
@Bean
@Primary
@ConfigurationProperties("vcap.services")
public HashMap<String, DataSourceServices.DataSourceObject> getCUPS() {
return new HashMap<>();
}
}
package com.example.fce.bas.database;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.springframework.stereotype.Component;
import java.util.HashMap;
@Data
@AllArgsConstructor
public class DataSourceServices {
private HashMap<String, DataSourceObject> dataSourceServices;
@Data
@Component
public static class DataSourceObject {
private DataSourceCredentials credentials;
@SuppressWarnings("checkstyle:membername")
private String syslog_drain_url;
@SuppressWarnings("checkstyle:membername")
private Object volume_mounts;
private String label;
private String name;
}
@Component
@Data
public static class DataSourceCredentials {
private String type;
private String as400Url;
private String jdbcUrl;
private String username;
private String password;
private String driverClassName;
private String connectionTestQuery;
private String location;
private int maximumPoolSize;
private int minimumIdle;
private long idleTimeout;
private long maxLifetime;
}
}
package com.example.fce.bas.database;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ibm.as400.access.AS400;
import com.ibm.as400.access.AS400SecurityException;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.util.StringUtils;
import javax.sql.DataSource;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class DatabaseConfiguration {
private final DataSourceServices cups;
@Autowired
public DatabaseConfiguration(DataSourceServices cups) {
this.cups = cups;
}
@Bean
@Primary
public DataSource dataSource() {
return getDataSources(this.cups);
}
@Bean
public HashMap<String, AS400> as400() {
return getAs400List(this.cups);
}
private DataSource getDataSources(DataSourceServices dataSourceServices) {
final DataSource[] defaultDatasource = {null};
DataSourceRouter routingDataSource = null;
Map<Object, Object> targetDataSources = new HashMap<>();
if (dataSourceServices.getDataSourceServices() != null) {
routingDataSource = new DataSourceRouter();
dataSourceServices.getDataSourceServices().keySet().forEach(k -> {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
DataSourceServices.DataSourceObject dataSourceObject = mapper.convertValue(
cups.getDataSourceServices().get(k),
DataSourceServices.DataSourceObject.class);
if (dataSourceObject.getLabel().equals("user-provided")
&& dataSourceObject.getCredentials().getType().equals("datasource")) {
String url = dataSourceObject.getCredentials().getJdbcUrl();
String user = dataSourceObject.getCredentials().getUsername();
String password = dataSourceObject.getCredentials().getPassword();
String driverClassName = dataSourceObject.getCredentials().getDriverClassName();
String connectionTestQuery = dataSourceObject.getCredentials().getConnectionTestQuery();
String location = dataSourceObject.getCredentials().getLocation();
int maximumPoolSize = dataSourceObject.getCredentials().getMaximumPoolSize();
int minimumIdle = dataSourceObject.getCredentials().getMinimumIdle();
long idleTimeout = dataSourceObject.getCredentials().getIdleTimeout();
long maxLifetime = dataSourceObject.getCredentials().getMaxLifetime();
defaultDatasource[0] = createDataSource(url, user, password, driverClassName, connectionTestQuery,
maximumPoolSize, minimumIdle, idleTimeout, maxLifetime);
targetDataSources.put(location, createDataSource(url, user, password, driverClassName, connectionTestQuery,
maximumPoolSize, minimumIdle, idleTimeout, maxLifetime));
}
});
routingDataSource.setTargetDataSources(targetDataSources);
routingDataSource.setDefaultTargetDataSource(defaultDatasource[0]);
}
return routingDataSource;
}
private HashMap<String, AS400> getAs400List(DataSourceServices dataSourceServices) {
HashMap<String, AS400> targetAS400 = new HashMap<>();
if (dataSourceServices.getDataSourceServices() != null) {
dataSourceServices.getDataSourceServices().keySet().forEach(k -> {
DataSourceServices.DataSourceObject dataSourceObject = getDataSourceObject(k);
if (dataSourceObject.getLabel().equals("user-provided") && dataSourceObject.getCredentials().getType().equals("datasource")) {
String url = dataSourceObject.getCredentials().getAs400Url();
String user = dataSourceObject.getCredentials().getUsername();
String password = dataSourceObject.getCredentials().getPassword();
String location = dataSourceObject.getCredentials().getLocation();
targetAS400.put(location, createAS400(url, user, password));
}
});
}
return targetAS400;
}
private DataSource createDataSource(String dataSourceUrl,
String dataSourceUser,
String dataSourcePassword,
String dataSourceDriverClassName,
String dataSourceConnectionTestQuery,
int maximumPoolSize,
int minimumIdle,
long idleTimeout,
long maxLifetime) {
String dataSourceUrlOrNull = stringOrNull(dataSourceUrl);
if (dataSourceUrlOrNull == null) {
return null;
}
HikariDataSource ds = new HikariDataSource();
ds.setJdbcUrl(dataSourceUrlOrNull);
ds.setUsername(stringOrNull(dataSourceUser));
ds.setPassword(stringOrNull(dataSourcePassword));
ds.setDriverClassName(stringOrNull(dataSourceDriverClassName));
ds.setConnectionTestQuery(stringOrNull(dataSourceConnectionTestQuery));
ds.setMaximumPoolSize(maximumPoolSize);
ds.setMinimumIdle(minimumIdle);
ds.setIdleTimeout(idleTimeout);
ds.setMaxLifetime(maxLifetime);
return ds;
}
private AS400 createAS400(String dataSourceUrl,
String dataSourceUser,
String dataSourcePassword) {
AS400 as400 = new AS400(dataSourceUrl, dataSourceUser, dataSourcePassword);
try {
as400.validateSignon(dataSourceUser, dataSourcePassword);
System.out.println("AS400 Sign on validated for " + dataSourceUser + " in " + dataSourceUrl);
} catch (AS400SecurityException | IOException e) {
e.printStackTrace();
}
return as400;
}
private DataSourceServices.DataSourceObject getDataSourceObject(String k) {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return mapper.convertValue(cups.getDataSourceServices().get(k), DataSourceServices.DataSourceObject.class);
}
private String stringOrNull(String value) {
return StringUtils.isEmpty(value) ? null : value;
}
}