Skip to content

Commit 3fec411

Browse files
committed
Ensure that Batch schema is in place before DB is accessed
Fixes gh-27193
1 parent 42e556d commit 3fec411

File tree

2 files changed

+37
-5
lines changed

2 files changed

+37
-5
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.java

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 the original author or authors.
2+
* Copyright 2012-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -27,8 +27,10 @@
2727
import org.springframework.batch.core.repository.JobRepository;
2828
import org.springframework.beans.factory.ObjectProvider;
2929
import org.springframework.boot.ExitCodeGenerator;
30+
import org.springframework.boot.autoconfigure.AbstractDependsOnBeanFactoryPostProcessor;
3031
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
3132
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
33+
import org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration.DataSourceInitializerConfiguration.DataSourceInitializationJobRepositoryDependencyConfiguration;
3234
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
3335
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
3436
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -100,9 +102,11 @@ public SimpleJobOperator jobOperator(ObjectProvider<JobParametersConverter> jobP
100102
return factory;
101103
}
102104

103-
@Configuration(proxyBeanMethods = false)
104-
@ConditionalOnBean(DataSource.class)
105-
@ConditionalOnClass(DatabasePopulator.class)
105+
// Fully-qualified to work around javac bug
106+
@org.springframework.context.annotation.Configuration(proxyBeanMethods = false)
107+
@org.springframework.boot.autoconfigure.condition.ConditionalOnBean(DataSource.class)
108+
@org.springframework.boot.autoconfigure.condition.ConditionalOnClass(DatabasePopulator.class)
109+
@org.springframework.context.annotation.Import(DataSourceInitializationJobRepositoryDependencyConfiguration.class)
106110
static class DataSourceInitializerConfiguration {
107111

108112
@Bean
@@ -114,6 +118,19 @@ BatchDataSourceInitializer batchDataSourceInitializer(DataSource dataSource,
114118
properties);
115119
}
116120

121+
/**
122+
* Post processor to ensure that {@link JobRepository} beans depend on any
123+
* {@link BatchDataSourceInitializer} beans.
124+
*/
125+
static class DataSourceInitializationJobRepositoryDependencyConfiguration
126+
extends AbstractDependsOnBeanFactoryPostProcessor {
127+
128+
DataSourceInitializationJobRepositoryDependencyConfiguration() {
129+
super(JobRepository.class, BatchDataSourceInitializer.class);
130+
}
131+
132+
}
133+
117134
}
118135

119136
}

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationTests.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors.
2+
* Copyright 2012-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -39,6 +39,7 @@
3939
import org.springframework.batch.core.launch.JobLauncher;
4040
import org.springframework.batch.core.repository.JobRepository;
4141
import org.springframework.beans.factory.annotation.Autowired;
42+
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
4243
import org.springframework.boot.CommandLineRunner;
4344
import org.springframework.boot.DefaultApplicationArguments;
4445
import org.springframework.boot.autoconfigure.AutoConfigurations;
@@ -268,6 +269,20 @@ void testBatchDataSource() {
268269
});
269270
}
270271

272+
@Test
273+
void jobRepositoryBeansDependOnBatchDataSourceInitializer() {
274+
this.contextRunner.withUserConfiguration(TestConfiguration.class, EmbeddedDataSourceConfiguration.class)
275+
.run((context) -> {
276+
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
277+
String[] jobRepositoryNames = beanFactory.getBeanNamesForType(JobRepository.class);
278+
assertThat(jobRepositoryNames).isNotEmpty();
279+
for (String jobRepositoryName : jobRepositoryNames) {
280+
assertThat(beanFactory.getBeanDefinition(jobRepositoryName).getDependsOn())
281+
.contains("batchDataSourceInitializer");
282+
}
283+
});
284+
}
285+
271286
@Configuration(proxyBeanMethods = false)
272287
protected static class BatchDataSourceConfiguration {
273288

0 commit comments

Comments
 (0)