У меня есть проект Springboot с внедренным многопользовательским режимом hibernate, у меня есть несколько источников данных, которые поступают из конечной точки REST, но я видел, что при запуске Springboot вызывает метод selectAnyDataSource (), и если у этой конкретной записи есть какое-то неправильное значение, загрузка при загрузке завершается неудачно, япопытался добавить обработку исключений, но код никогда не проходит через мой блок catch или метод, аннотированный с ExceptionHandler, который находится внутри класса, аннотированного с помощью Controller Advice.
Я уже пробовал объявлять catch и метод, аннотированный с ExceptionHandler, со всеми исключениямиИерархия классов и поставить точку останова, но код никогда не проходит через них.
Это мои классы конфигурации:
@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);
}
}
Мне это нужно, если по какой-то причине база данных, где я пытаюсьподключение недоступно, я могу обработать исключение, и приложение продолжает работать.