创建异常以处理Hibernate Multitenant项目上的DataSourceCreation错误

时间:2019-02-13 23:11:14

标签: hibernate spring-boot multi-tenant

我有一个实现了休眠多租户的Springboot项目,我有几个来自REST端点的数据源,但是我看到Springboot在启动时调用方法selectAnyDataSource(),如果该特定条目的值不正确,则引导程序将失败,我试图添加异常处理,但代码从未通过我的catch块或使用Controller注释的类中的ExceptionHandler注释的方法。

我已经尝试用所有Exception类层次结构声明用ExceptionHandler注释的catch和方法,并在其上设置一个断点,但是代码从未经过它们。

这是我的配置类:

@Configuration
@EnableConfigurationProperties({ JpaProperties.class })
@EnableTransactionManagement(proxyTargetClass=true)
@EnableJpaRepositories(basePackages= {"com.intraway.qx.schedule.model.repository"},transactionManagerRef="transactionManager")
public class MultiTenantJpaConfiguration {

    private final DataSourceProperties properties;

    private final JpaProperties jpaProperties;

    @Value("${getDataSourcesEndpoint}")
    private String DataSourceEndpoint;

    @Autowired
    public MultiTenantJpaConfiguration(DataSourceProperties properties, JpaProperties jpaProperties) {
        this.properties = properties;
        this.jpaProperties = jpaProperties;
    }

    @Bean
    public MultiTenantConnectionProvider multiTenantConnectionProvider() {
        return new DataSourceBasedMultiTenantConnectionProviderImpl();
    }

    @Bean
    public CurrentTenantIdentifierResolver currentTenantIdentifierResolver() {
        return new CurrentTenantIdentifierResolverImpl();
    }

    @Bean(name = "mars2DataSources" )
    public Map<String, DataSource> mars2DataSources() {

        Map<String, DataSource> datasources = new HashMap<>();

        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<BmonitorDataSource[]> responseEntity = restTemplate.getForEntity(DataSourceEndpoint, BmonitorDataSource[].class);
        BmonitorDataSource[] bmonitorDataSources = responseEntity.getBody();

        for (BmonitorDataSource bmonitorDataSource : bmonitorDataSources) {
            String tenantId = bmonitorDataSource.getTenantId();
            datasources.put(tenantId,
                    DataSourceBuilder.create(this.getClass().getClassLoader())
                            .driverClassName(properties.getDriverClassName())
                            .url("jdbc:mysql://localhost:" +bmonitorDataSource.getDbPort() +"/" + bmonitorDataSource.getDbSchemaName() + "?useSSL=false")
                            .username(bmonitorDataSource.getDataSourceUsername())
                            .password(bmonitorDataSource.getDataSourcePassword())
                            .build()
            );
        }
         return datasources;
    }

    @PersistenceContext @Primary @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(MultiTenantConnectionProvider multiTenantConnectionProvider,
        CurrentTenantIdentifierResolver currentTenantIdentifierResolver) {

        Map<String, Object> hibernateProps = new LinkedHashMap<>();
        hibernateProps.putAll(this.jpaProperties.getProperties());
        hibernateProps.put(Environment.MULTI_TENANT, MultiTenancyStrategy.DATABASE);
        hibernateProps.put(Environment.MULTI_TENANT_CONNECTION_PROVIDER, multiTenantConnectionProvider);
        hibernateProps.put(Environment.MULTI_TENANT_IDENTIFIER_RESOLVER, currentTenantIdentifierResolver);
        hibernateProps.put(Environment.AUTOCOMMIT, false);
        hibernateProps.put("org.hibernate.FlushMode", "manual");

        // No dataSource is set to resulting entityManagerFactoryBean
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setPackagesToScan(new String[] { BmonitorDataSource.class.getPackage().getName() });
        em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        em.setJpaPropertyMap(hibernateProps);

        return em;
    }

    @Bean
    public EntityManagerFactory entityManagerFactory(LocalContainerEntityManagerFactoryBean entityManagerFactoryBean) {
        return entityManagerFactoryBean.getObject();
    }

    @Bean(name="transactionManager")
    public PlatformTransactionManager txManager(EntityManagerFactory entityManagerFactory) {
        JpaTransactionManager jpa = new JpaTransactionManager ();
        jpa.setEntityManagerFactory(entityManagerFactory);
        return jpa;
    }


    public class DataSourceBasedMultiTenantConnectionProviderImpl extends AbstractDataSourceBasedMultiTenantConnectionProviderImpl {

    private static final long serialVersionUID = 1L;

    @Autowired
    private Map<String,DataSource> mars2DataSources;

    @Bean
    @Override
    public DataSource selectAnyDataSource() {
        try {
           return this.mars2DataSources.values().iterator().next();
        }
        catch (Throwable ex) {
            return this.mars2DataSources.values().iterator().next();
        }

    }

    @Override
    public DataSource selectDataSource(String tenantId) {
        return this.mars2DataSources.get(tenantId);
    }
}

我需要,如果由于某种原因,我尝试连接的数据库不可用,我可以处理异常,并且应用程序可以正常工作。

0 个答案:

没有答案