Skip to content

Commit 7a9a2a9

Browse files
fmbenhassinemminella
authored andcommitted
BATCH-2537: add support for @primary annotated data sources
Currently, when multiple data sources are defined in the context, an IllegalStateException is thrown even if one of the data sources is annotated with @primary (which should be the one to use). This commit makes it possible to use the data source annotated with @primary when multiple data sources are defined. Note that the context initialization will still fail (with a UnsatisfiedDependencyException from Spring's bean factory) if multiple data sources are defined and none of them is annotated with @primary. If multiple data sources are defined and none of them is annotated with @primary but one of them is named "dataSource", this data source will be used by the batch configuration due to autowiring by name (this detail has been documented in the javadoc of @EnableBatchProcessing). Resolves BATCH-2537
1 parent 98add33 commit 7a9a2a9

File tree

3 files changed

+56
-14
lines changed

3 files changed

+56
-14
lines changed

spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/AbstractBatchConfiguration.java

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2013 the original author or authors.
2+
* Copyright 2012-2018 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.
@@ -41,6 +41,7 @@
4141
*
4242
* @author Dave Syer
4343
* @author Michael Minella
44+
* @author Mahmoud Ben Hassine
4445
* @since 2.2
4546
* @see EnableBatchProcessing
4647
*/
@@ -49,7 +50,7 @@
4950
public abstract class AbstractBatchConfiguration implements ImportAware {
5051

5152
@Autowired(required = false)
52-
private Collection<DataSource> dataSources;
53+
private DataSource dataSource;
5354

5455
private BatchConfigurer configurer;
5556

@@ -93,20 +94,16 @@ protected BatchConfigurer getConfigurer(Collection<BatchConfigurer> configurers)
9394
return this.configurer;
9495
}
9596
if (configurers == null || configurers.isEmpty()) {
96-
if (dataSources == null || dataSources.isEmpty()) {
97+
if (dataSource == null) {
9798
DefaultBatchConfigurer configurer = new DefaultBatchConfigurer();
9899
configurer.initialize();
99100
this.configurer = configurer;
100101
return configurer;
101-
} else if(dataSources != null && dataSources.size() == 1) {
102-
DataSource dataSource = dataSources.iterator().next();
102+
} else {
103103
DefaultBatchConfigurer configurer = new DefaultBatchConfigurer(dataSource);
104104
configurer.initialize();
105105
this.configurer = configurer;
106106
return configurer;
107-
} else {
108-
throw new IllegalStateException("To use the default BatchConfigurer the context must contain no more than " +
109-
"one DataSource, found " + dataSources.size());
110107
}
111108
}
112109
if (configurers.size() > 1) {
@@ -144,4 +141,4 @@ public JobScope jobScope() {
144141
jobScope.setAutoProxy(false);
145142
return jobScope;
146143
}
147-
}
144+
}

spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/EnableBatchProcessing.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2014 the original author or authors.
2+
* Copyright 2012-2018 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,6 +27,7 @@
2727
import org.springframework.batch.core.configuration.support.AutomaticJobRegistrar;
2828
import org.springframework.batch.core.launch.JobLauncher;
2929
import org.springframework.batch.core.repository.JobRepository;
30+
import org.springframework.beans.factory.UnsatisfiedDependencyException;
3031
import org.springframework.context.annotation.Import;
3132
import org.springframework.transaction.PlatformTransactionManager;
3233

@@ -85,7 +86,12 @@
8586
* </pre>
8687
*
8788
* If a user does not provide a {@link javax.sql.DataSource} within the context, a Map based
88-
* {@link org.springframework.batch.core.repository.JobRepository} will be used.
89+
* {@link org.springframework.batch.core.repository.JobRepository} will be used. If multiple
90+
* {@link javax.sql.DataSource}s are defined in the context, the one annotated with
91+
* {@link org.springframework.context.annotation.Primary} will be used (Note that if none
92+
* of them is annotated with {@link org.springframework.context.annotation.Primary}, the one
93+
* named <code>dataSource</code> will be used if any, otherwise a {@link UnsatisfiedDependencyException}
94+
* will be thrown).
8995
*
9096
* Note that only one of your configuration classes needs to have the <code>&#064;EnableBatchProcessing</code>
9197
* annotation. Once you have an <code>&#064;EnableBatchProcessing</code> class in your configuration you will have an
@@ -156,6 +162,7 @@
156162
* </pre>
157163
*
158164
* @author Dave Syer
165+
* @author Mahmoud Ben Hassine
159166
*
160167
*/
161168
@Target(ElementType.TYPE)

spring-batch-core/src/test/java/org/springframework/batch/core/configuration/annotation/MapJobRepositoryConfigurationTests.java

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,11 @@
3333
import org.springframework.batch.core.scope.context.ChunkContext;
3434
import org.springframework.batch.core.step.tasklet.Tasklet;
3535
import org.springframework.batch.repeat.RepeatStatus;
36+
import org.springframework.beans.factory.UnsatisfiedDependencyException;
3637
import org.springframework.beans.factory.annotation.Autowired;
3738
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
3839
import org.springframework.context.annotation.Bean;
40+
import org.springframework.context.annotation.Primary;
3941
import org.springframework.context.support.GenericApplicationContext;
4042
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
4143
import org.springframework.stereotype.Component;
@@ -57,11 +59,21 @@ public void testOneDataSource() throws Exception {
5759
testConfigurationClass(HsqlBatchConfiguration.class);
5860
}
5961

60-
@Test(expected = IllegalStateException.class)
61-
public void testMultipleDataSources() throws Exception {
62+
@Test(expected = UnsatisfiedDependencyException.class)
63+
public void testMultipleDataSources_whenNoneOfThemIsPrimary() throws Exception {
6264
testConfigurationClass(InvalidBatchConfiguration.class);
6365
}
6466

67+
@Test
68+
public void testMultipleDataSources_whenNoneOfThemIsPrimaryButOneOfThemIsNamed_dataSource_() throws Exception {
69+
testConfigurationClass(ValidBatchConfigurationWithoutPrimaryDataSource.class);
70+
}
71+
72+
@Test
73+
public void testMultipleDataSources_whenOneOfThemIsPrimary() throws Exception {
74+
testConfigurationClass(ValidBatchConfigurationWithPrimaryDataSource.class);
75+
}
76+
6577
private void testConfigurationClass(Class<?> clazz) throws Exception {
6678
GenericApplicationContext context = new AnnotationConfigApplicationContext(clazz);
6779
this.jobLauncher = context.getBean(JobLauncher.class);
@@ -85,11 +97,37 @@ DataSource dataSource2() {
8597
}
8698
}
8799

100+
public static class ValidBatchConfigurationWithPrimaryDataSource extends HsqlBatchConfiguration {
101+
102+
@Primary
103+
@Bean
104+
DataSource dataSource2() {
105+
return new PooledEmbeddedDataSource(new EmbeddedDatabaseBuilder().
106+
setName("dataSource2").
107+
addScript("classpath:org/springframework/batch/core/schema-drop-hsqldb.sql").
108+
addScript("classpath:org/springframework/batch/core/schema-hsqldb.sql").
109+
build());
110+
}
111+
}
112+
113+
public static class ValidBatchConfigurationWithoutPrimaryDataSource extends HsqlBatchConfiguration {
114+
115+
@Bean
116+
DataSource dataSource() { // will be autowired by name
117+
return new PooledEmbeddedDataSource(new EmbeddedDatabaseBuilder().
118+
setName("dataSource").
119+
addScript("classpath:org/springframework/batch/core/schema-drop-hsqldb.sql").
120+
addScript("classpath:org/springframework/batch/core/schema-hsqldb.sql").
121+
build());
122+
}
123+
}
124+
88125
public static class HsqlBatchConfiguration extends MapRepositoryBatchConfiguration {
89126

90127
@Bean
91-
DataSource dataSource() {
128+
DataSource dataSource1() {
92129
return new PooledEmbeddedDataSource(new EmbeddedDatabaseBuilder().
130+
setName("dataSource1").
93131
addScript("classpath:org/springframework/batch/core/schema-drop-hsqldb.sql").
94132
addScript("classpath:org/springframework/batch/core/schema-hsqldb.sql").
95133
build());

0 commit comments

Comments
 (0)