diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/AbstractBatchConfiguration.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/AbstractBatchConfiguration.java index ce714604b..92323de7f 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/AbstractBatchConfiguration.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/AbstractBatchConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2013 the original author or authors. + * Copyright 2012-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,6 +41,7 @@ import java.util.Collection; * * @author Dave Syer * @author Michael Minella + * @author Mahmoud Ben Hassine * @since 2.2 * @see EnableBatchProcessing */ @@ -49,7 +50,7 @@ import java.util.Collection; public abstract class AbstractBatchConfiguration implements ImportAware { @Autowired(required = false) - private Collection dataSources; + private DataSource dataSource; private BatchConfigurer configurer; @@ -93,20 +94,16 @@ public abstract class AbstractBatchConfiguration implements ImportAware { return this.configurer; } if (configurers == null || configurers.isEmpty()) { - if (dataSources == null || dataSources.isEmpty()) { + if (dataSource == null) { DefaultBatchConfigurer configurer = new DefaultBatchConfigurer(); configurer.initialize(); this.configurer = configurer; return configurer; - } else if(dataSources != null && dataSources.size() == 1) { - DataSource dataSource = dataSources.iterator().next(); + } else { DefaultBatchConfigurer configurer = new DefaultBatchConfigurer(dataSource); configurer.initialize(); this.configurer = configurer; return configurer; - } else { - throw new IllegalStateException("To use the default BatchConfigurer the context must contain no more than " + - "one DataSource, found " + dataSources.size()); } } if (configurers.size() > 1) { @@ -144,4 +141,4 @@ class ScopeConfiguration { jobScope.setAutoProxy(false); return jobScope; } -} \ No newline at end of file +} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/EnableBatchProcessing.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/EnableBatchProcessing.java index da35e10d5..5fa35dfb2 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/EnableBatchProcessing.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/EnableBatchProcessing.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * Copyright 2012-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,6 +27,7 @@ import org.springframework.batch.core.configuration.support.ApplicationContextFa import org.springframework.batch.core.configuration.support.AutomaticJobRegistrar; import org.springframework.batch.core.launch.JobLauncher; import org.springframework.batch.core.repository.JobRepository; +import org.springframework.beans.factory.UnsatisfiedDependencyException; import org.springframework.context.annotation.Import; import org.springframework.transaction.PlatformTransactionManager; @@ -85,7 +86,12 @@ import org.springframework.transaction.PlatformTransactionManager; * * * If a user does not provide a {@link javax.sql.DataSource} within the context, a Map based - * {@link org.springframework.batch.core.repository.JobRepository} will be used. + * {@link org.springframework.batch.core.repository.JobRepository} will be used. If multiple + * {@link javax.sql.DataSource}s are defined in the context, the one annotated with + * {@link org.springframework.context.annotation.Primary} will be used (Note that if none + * of them is annotated with {@link org.springframework.context.annotation.Primary}, the one + * named dataSource will be used if any, otherwise a {@link UnsatisfiedDependencyException} + * will be thrown). * * Note that only one of your configuration classes needs to have the @EnableBatchProcessing * annotation. Once you have an @EnableBatchProcessing class in your configuration you will have an @@ -156,6 +162,7 @@ import org.springframework.transaction.PlatformTransactionManager; * * * @author Dave Syer + * @author Mahmoud Ben Hassine * */ @Target(ElementType.TYPE) diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/annotation/MapJobRepositoryConfigurationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/annotation/MapJobRepositoryConfigurationTests.java index 7bff0fcbd..b45ac65b5 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/annotation/MapJobRepositoryConfigurationTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/annotation/MapJobRepositoryConfigurationTests.java @@ -33,9 +33,11 @@ import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.core.scope.context.ChunkContext; import org.springframework.batch.core.step.tasklet.Tasklet; import org.springframework.batch.repeat.RepeatStatus; +import org.springframework.beans.factory.UnsatisfiedDependencyException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Primary; import org.springframework.context.support.GenericApplicationContext; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.stereotype.Component; @@ -57,11 +59,21 @@ public class MapJobRepositoryConfigurationTests { testConfigurationClass(HsqlBatchConfiguration.class); } - @Test(expected = IllegalStateException.class) - public void testMultipleDataSources() throws Exception { + @Test(expected = UnsatisfiedDependencyException.class) + public void testMultipleDataSources_whenNoneOfThemIsPrimary() throws Exception { testConfigurationClass(InvalidBatchConfiguration.class); } + @Test + public void testMultipleDataSources_whenNoneOfThemIsPrimaryButOneOfThemIsNamed_dataSource_() throws Exception { + testConfigurationClass(ValidBatchConfigurationWithoutPrimaryDataSource.class); + } + + @Test + public void testMultipleDataSources_whenOneOfThemIsPrimary() throws Exception { + testConfigurationClass(ValidBatchConfigurationWithPrimaryDataSource.class); + } + private void testConfigurationClass(Class clazz) throws Exception { GenericApplicationContext context = new AnnotationConfigApplicationContext(clazz); this.jobLauncher = context.getBean(JobLauncher.class); @@ -85,11 +97,37 @@ public class MapJobRepositoryConfigurationTests { } } + public static class ValidBatchConfigurationWithPrimaryDataSource extends HsqlBatchConfiguration { + + @Primary + @Bean + DataSource dataSource2() { + return new PooledEmbeddedDataSource(new EmbeddedDatabaseBuilder(). + setName("dataSource2"). + addScript("classpath:org/springframework/batch/core/schema-drop-hsqldb.sql"). + addScript("classpath:org/springframework/batch/core/schema-hsqldb.sql"). + build()); + } + } + + public static class ValidBatchConfigurationWithoutPrimaryDataSource extends HsqlBatchConfiguration { + + @Bean + DataSource dataSource() { // will be autowired by name + return new PooledEmbeddedDataSource(new EmbeddedDatabaseBuilder(). + setName("dataSource"). + addScript("classpath:org/springframework/batch/core/schema-drop-hsqldb.sql"). + addScript("classpath:org/springframework/batch/core/schema-hsqldb.sql"). + build()); + } + } + public static class HsqlBatchConfiguration extends MapRepositoryBatchConfiguration { @Bean - DataSource dataSource() { + DataSource dataSource1() { return new PooledEmbeddedDataSource(new EmbeddedDatabaseBuilder(). + setName("dataSource1"). addScript("classpath:org/springframework/batch/core/schema-drop-hsqldb.sql"). addScript("classpath:org/springframework/batch/core/schema-hsqldb.sql"). build());