Hibernate Spring boot AbstractRoutingDataSource

Hibernate Spring boot AbstractRoutingDataSource,hibernate,spring-boot,datasource,spring-data-jpa,multi-tenant,Hibernate,Spring Boot,Datasource,Spring Data Jpa,Multi Tenant,我试图使用AbstractRoutingDataSource创建一个动态数据源(基于会话),但spring boot在启动时一直调用AbstractRoutingDataSource的determineCurrentLookupKey()函数 @ConfigurationProperties(prefix = "datasource.int") @Bean public DataSource internal() { return DataSourceBuilder.create().b

我试图使用AbstractRoutingDataSource创建一个动态数据源(基于会话),但spring boot在启动时一直调用AbstractRoutingDataSource的determineCurrentLookupKey()函数

@ConfigurationProperties(prefix = "datasource.int")
@Bean
public DataSource internal() {
    return DataSourceBuilder.create().build();

}

@ConfigurationProperties(prefix = "datasource.ext")
@Bean
public DataSource external() {
    return DataSourceBuilder.create().build();
}

@Bean(name = "dataSource")
@Qualifier("dataSource")
public DynamicRoutingDataSourceResolver dataSource() {
    DynamicRoutingDataSourceResolver resolver = new DynamicRoutingDataSourceResolver();
    DataSource internal = internal();
    DataSource external = external();
    Map<Object, Object> dataSources = new HashMap<>();
    dataSources.put(env.getRequiredProperty("app.param.int"), internal);
    dataSources.put(env.getRequiredProperty("app.param.ext"), external);
    resolver.setDefaultTargetDataSource(internal);
    resolver.setTargetDataSources(dataSources);
    resolver.afterPropertiesSet();

    return resolver;
}

public class DynamicRoutingDataSourceResolver extends  AbstractRoutingDataSource {

@Override
protected Object determineCurrentLookupKey() {

    HttpServletRequest request = ((ServletRequestAttributes)  RequestContextHolder.getRequestAttributes()).getRequest();
    Object o = request.getSession().getAttribute(Constant.DATASOURCE);
    return o;

}
@ConfigurationProperties(prefix=“datasource.int”)
@豆子
公共数据源内部(){
返回DataSourceBuilder.create().build();
}
@ConfigurationProperties(前缀=“datasource.ext”)
@豆子
公共数据源外部(){
返回DataSourceBuilder.create().build();
}
@Bean(name=“dataSource”)
@限定符(“数据源”)
公共DynamicRoutingDataSourceSolver数据源(){
DynamicRoutingDataSourceResolver解析器=新建DynamicRoutingDataSourceResolver();
DataSource internal=internal();
DataSource external=external();
Map dataSources=newhashmap();
dataSources.put(env.getRequiredProperty(“app.param.int”),内部);
dataSources.put(env.getRequiredProperty(“app.param.ext”),外部的;
resolver.setDefaultTargetDataSource(内部);
resolver.setTargetDataSources(数据源);
解析程序。AfterPropertieSet();
返回解析器;
}
公共类DynamicRoutingDataSourceSolver扩展了AbstractRoutingDataSource{
@凌驾
受保护的对象确定当前查找键(){
HttpServletRequest请求=((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
对象o=request.getSession().getAttribute(常量.DATASOURCE);
返回o;
}
}

它抛出NullPointerException,因为RequestAttributes为null。 我试图将@Primary放入其中一个数据源中,但在我尝试执行查询时,AbstractRoutingDataSource determineCurrentLookupKey()未被触发

我使用的是spring数据jpa


另请参见

此处不必指定任何形式的
@Primary

只需创建所有数据源并将其分配给
AbstractRoutingDataSource
。如果有一个数据源是默认数据源,也可以使用
#setDefaultTargetDataSource
进行设置,就像代码显示的那样

在您的例子中,
NullPointerException
只是您的代码需要防范的东西。如果发现解析程序中不存在请求数据,只需为数据源查找键返回一个
null


AbstractRoutingDataSource
使用默认数据源,如果返回的查找键为
null
,或者指定的键未通过查找映射定义为数据源。

您不必在此处指定任何形式的
@Primary

只需创建所有数据源并将其分配给
AbstractRoutingDataSource
。如果有一个数据源是默认数据源,也可以使用
#setDefaultTargetDataSource
进行设置,就像代码显示的那样

在您的例子中,
NullPointerException
只是您的代码需要防范的东西。如果发现解析程序中不存在请求数据,只需为数据源查找键返回一个
null

AbstractRoutingDataSource
如果返回的查找键为
null
或指定的键未通过查找映射定义为数据源,则使用定义的默认数据源