diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BasicBatchConfigurer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BasicBatchConfigurer.java index c86f638939..15f8ca3e36 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BasicBatchConfigurer.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BasicBatchConfigurer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2021 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. @@ -111,7 +111,7 @@ public class BasicBatchConfigurer implements BatchConfigurer, InitializingBean { PropertyMapper map = PropertyMapper.get(); JobExplorerFactoryBean factory = new JobExplorerFactoryBean(); factory.setDataSource(this.dataSource); - map.from(this.properties::getTablePrefix).whenHasText().to(factory::setTablePrefix); + map.from(this.properties.getJdbc()::getTablePrefix).whenHasText().to(factory::setTablePrefix); factory.afterPropertiesSet(); return factory.getObject(); } @@ -128,7 +128,7 @@ public class BasicBatchConfigurer implements BatchConfigurer, InitializingBean { PropertyMapper map = PropertyMapper.get(); map.from(this.dataSource).to(factory::setDataSource); map.from(this::determineIsolationLevel).whenNonNull().to(factory::setIsolationLevelForCreate); - map.from(this.properties::getTablePrefix).whenHasText().to(factory::setTablePrefix); + map.from(this.properties.getJdbc()::getTablePrefix).whenHasText().to(factory::setTablePrefix); map.from(this::getTransactionManager).to(factory::setTransactionManager); factory.afterPropertiesSet(); return factory.getObject(); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchDataSourceInitializer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchDataSourceInitializer.java index 4abf9de4a0..b642fe2f44 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchDataSourceInitializer.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchDataSourceInitializer.java @@ -18,6 +18,7 @@ package org.springframework.boot.autoconfigure.batch; import javax.sql.DataSource; +import org.springframework.boot.autoconfigure.batch.BatchProperties.Jdbc; import org.springframework.boot.jdbc.AbstractDataSourceInitializer; import org.springframework.boot.jdbc.DataSourceInitializationMode; import org.springframework.core.io.ResourceLoader; @@ -32,23 +33,23 @@ import org.springframework.util.Assert; */ public class BatchDataSourceInitializer extends AbstractDataSourceInitializer { - private final BatchProperties properties; + private final Jdbc jdbcProperties; public BatchDataSourceInitializer(DataSource dataSource, ResourceLoader resourceLoader, BatchProperties properties) { super(dataSource, resourceLoader); Assert.notNull(properties, "BatchProperties must not be null"); - this.properties = properties; + this.jdbcProperties = properties.getJdbc(); } @Override protected DataSourceInitializationMode getMode() { - return this.properties.getInitializeSchema(); + return this.jdbcProperties.getInitializeSchema(); } @Override protected String getSchemaLocation() { - return this.properties.getSchema(); + return this.jdbcProperties.getSchema(); } @Override diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchProperties.java index d1bdbc0cba..89760536b3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2021 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. @@ -17,6 +17,7 @@ package org.springframework.boot.autoconfigure.batch; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.DeprecatedConfigurationProperty; import org.springframework.boot.jdbc.DataSourceInitializationMode; /** @@ -25,59 +26,72 @@ import org.springframework.boot.jdbc.DataSourceInitializationMode; * @author Stephane Nicoll * @author EddĂș MelĂ©ndez * @author Vedran Pavic + * @author Mukul Kumar Chaundhyan * @since 1.2.0 */ @ConfigurationProperties(prefix = "spring.batch") public class BatchProperties { - private static final String DEFAULT_SCHEMA_LOCATION = "classpath:org/springframework/" - + "batch/core/schema-@@platform@@.sql"; - - /** - * Path to the SQL file to use to initialize the database schema. - */ - private String schema = DEFAULT_SCHEMA_LOCATION; - - /** - * Table prefix for all the batch meta-data tables. - */ - private String tablePrefix; - - /** - * Database schema initialization mode. - */ - private DataSourceInitializationMode initializeSchema = DataSourceInitializationMode.EMBEDDED; - private final Job job = new Job(); + private final Jdbc jdbc = new Jdbc(); + + /** + * Return the datasource schema. + * @return the schema + * @deprecated as of 2.5.0 in favor of {@link Jdbc#getSchema()} + */ + @Deprecated + @DeprecatedConfigurationProperty(replacement = "spring.batch.jdbc.schema") public String getSchema() { - return this.schema; + return this.jdbc.getSchema(); } + @Deprecated public void setSchema(String schema) { - this.schema = schema; + this.jdbc.setSchema(schema); } + /** + * Return the table prefix. + * @return the table prefix + * @deprecated as of 2.5.0 in favor of {@link Jdbc#getTablePrefix()} + */ + @Deprecated + @DeprecatedConfigurationProperty(replacement = "spring.batch.jdbc.table-prefix") public String getTablePrefix() { - return this.tablePrefix; + return this.jdbc.getTablePrefix(); } + @Deprecated public void setTablePrefix(String tablePrefix) { - this.tablePrefix = tablePrefix; + this.jdbc.setTablePrefix(tablePrefix); } + /** + * Return whether the schema should be initialized. + * @return the initialization mode + * @deprecated as of 2.5.0 in favor of {@link Jdbc#getInitializeSchema()} + */ + @Deprecated + @DeprecatedConfigurationProperty(replacement = "spring.batch.jdbc.initialize-schema") public DataSourceInitializationMode getInitializeSchema() { - return this.initializeSchema; + return this.jdbc.getInitializeSchema(); } + @Deprecated public void setInitializeSchema(DataSourceInitializationMode initializeSchema) { - this.initializeSchema = initializeSchema; + this.jdbc.setInitializeSchema(initializeSchema); } public Job getJob() { return this.job; } + public Jdbc getJdbc() { + return this.jdbc; + } + public static class Job { /** @@ -96,4 +110,50 @@ public class BatchProperties { } + public static class Jdbc { + + private static final String DEFAULT_SCHEMA_LOCATION = "classpath:org/springframework/" + + "batch/core/schema-@@platform@@.sql"; + + /** + * Path to the SQL file to use to initialize the database schema. + */ + private String schema = DEFAULT_SCHEMA_LOCATION; + + /** + * Table prefix for all the batch meta-data tables. + */ + private String tablePrefix; + + /** + * Database schema initialization mode. + */ + private DataSourceInitializationMode initializeSchema = DataSourceInitializationMode.EMBEDDED; + + public String getSchema() { + return this.schema; + } + + public void setSchema(String schema) { + this.schema = schema; + } + + public String getTablePrefix() { + return this.tablePrefix; + } + + public void setTablePrefix(String tablePrefix) { + this.tablePrefix = tablePrefix; + } + + public DataSourceInitializationMode getInitializeSchema() { + return this.initializeSchema; + } + + public void setInitializeSchema(DataSourceInitializationMode initializeSchema) { + this.initializeSchema = initializeSchema; + } + + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 153254e79a..cb6fa6771e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -376,10 +376,14 @@ "type": "java.lang.Boolean", "description": "Create the required batch tables on startup if necessary. Enabled automatically\n if no custom table prefix is set or if a custom schema is configured.", "deprecation": { - "replacement": "spring.batch.initialize-schema", + "replacement": "spring.batch.jdbc.initialize-schema", "level": "error" } }, + { + "name": "spring.batch.jdbc.initialize-schema", + "defaultValue": "embedded" + }, { "name": "spring.batch.job.enabled", "type": "java.lang.Boolean", diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationTests.java index a00dfca3d0..c71d2f0bd1 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2021 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. @@ -49,7 +49,9 @@ import org.springframework.boot.autoconfigure.orm.jpa.test.City; import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.boot.jdbc.DataSourceInitializationMode; +import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.test.context.runner.ContextConsumer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; @@ -82,7 +84,7 @@ class BatchAutoConfigurationTests { .run((context) -> { assertThat(context).hasSingleBean(JobLauncher.class); assertThat(context).hasSingleBean(JobExplorer.class); - assertThat(context.getBean(BatchProperties.class).getInitializeSchema()) + assertThat(context.getBean(BatchProperties.class).getJdbc().getInitializeSchema()) .isEqualTo(DataSourceInitializationMode.EMBEDDED); assertThat(new JdbcTemplate(context.getBean(DataSource.class)) .queryForList("select * from BATCH_JOB_EXECUTION")).isEmpty(); @@ -174,17 +176,30 @@ class BatchAutoConfigurationTests { @Test void testDisableSchemaLoader() { + this.contextRunner.withUserConfiguration(TestConfiguration.class, EmbeddedDataSourceConfiguration.class) + .withPropertyValues("spring.datasource.generate-unique-name=true", + "spring.batch.jdbc.initialize-schema:never") + .run(assertDatasourceIsNotInitialized()); + } + + @Test + @Deprecated + void testDisableSchemaLoaderWithDeprecatedProperty() { this.contextRunner.withUserConfiguration(TestConfiguration.class, EmbeddedDataSourceConfiguration.class) .withPropertyValues("spring.datasource.generate-unique-name=true", "spring.batch.initialize-schema:never") - .run((context) -> { - assertThat(context).hasSingleBean(JobLauncher.class); - assertThat(context.getBean(BatchProperties.class).getInitializeSchema()) - .isEqualTo(DataSourceInitializationMode.NEVER); - assertThatExceptionOfType(BadSqlGrammarException.class) - .isThrownBy(() -> new JdbcTemplate(context.getBean(DataSource.class)) - .queryForList("select * from BATCH_JOB_EXECUTION")); - }); + .run(assertDatasourceIsNotInitialized()); + } + + private ContextConsumer assertDatasourceIsNotInitialized() { + return (context) -> { + assertThat(context).hasSingleBean(JobLauncher.class); + assertThat(context.getBean(BatchProperties.class).getJdbc().getInitializeSchema()) + .isEqualTo(DataSourceInitializationMode.NEVER); + assertThatExceptionOfType(BadSqlGrammarException.class) + .isThrownBy(() -> new JdbcTemplate(context.getBean(DataSource.class)) + .queryForList("select * from BATCH_JOB_EXECUTION")); + }; } @Test @@ -205,23 +220,39 @@ class BatchAutoConfigurationTests { @Test void testRenamePrefix() { + this.contextRunner + .withUserConfiguration(TestConfiguration.class, EmbeddedDataSourceConfiguration.class, + HibernateJpaAutoConfiguration.class) + .withPropertyValues("spring.datasource.generate-unique-name=true", + "spring.batch.jdbc.schema:classpath:batch/custom-schema-hsql.sql", + "spring.batch.jdbc.tablePrefix:PREFIX_") + .run(assertCustomTablePrefix()); + } + + @Test + @Deprecated + void testRenamePrefixWithDeprecatedProperty() { this.contextRunner .withUserConfiguration(TestConfiguration.class, EmbeddedDataSourceConfiguration.class, HibernateJpaAutoConfiguration.class) .withPropertyValues("spring.datasource.generate-unique-name=true", "spring.batch.schema:classpath:batch/custom-schema-hsql.sql", "spring.batch.tablePrefix:PREFIX_") - .run((context) -> { - assertThat(context).hasSingleBean(JobLauncher.class); - assertThat(context.getBean(BatchProperties.class).getInitializeSchema()) - .isEqualTo(DataSourceInitializationMode.EMBEDDED); - assertThat(new JdbcTemplate(context.getBean(DataSource.class)) - .queryForList("select * from PREFIX_JOB_EXECUTION")).isEmpty(); - JobExplorer jobExplorer = context.getBean(JobExplorer.class); - assertThat(jobExplorer.findRunningJobExecutions("test")).isEmpty(); - JobRepository jobRepository = context.getBean(JobRepository.class); - assertThat(jobRepository.getLastJobExecution("test", new JobParameters())).isNull(); - }); + .run(assertCustomTablePrefix()); + } + + private ContextConsumer assertCustomTablePrefix() { + return (context) -> { + assertThat(context).hasSingleBean(JobLauncher.class); + assertThat(context.getBean(BatchProperties.class).getJdbc().getInitializeSchema()) + .isEqualTo(DataSourceInitializationMode.EMBEDDED); + assertThat(new JdbcTemplate(context.getBean(DataSource.class)) + .queryForList("select * from PREFIX_JOB_EXECUTION")).isEmpty(); + JobExplorer jobExplorer = context.getBean(JobExplorer.class); + assertThat(jobExplorer.findRunningJobExecutions("test")).isEmpty(); + JobRepository jobRepository = context.getBean(JobRepository.class); + assertThat(jobRepository.getLastJobExecution("test", new JobParameters())).isNull(); + }; } @Test diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationWithoutJpaTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationWithoutJpaTests.java index 218660dfc4..a7bc4c83d4 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationWithoutJpaTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationWithoutJpaTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2021 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. @@ -31,7 +31,9 @@ import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfigurati import org.springframework.boot.autoconfigure.orm.jpa.test.City; import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; import org.springframework.boot.jdbc.DataSourceInitializationMode; +import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.test.context.runner.ContextConsumer; import org.springframework.boot.testsupport.classpath.ClassPathExclusions; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.transaction.PlatformTransactionManager; @@ -59,7 +61,7 @@ class BatchAutoConfigurationWithoutJpaTests { assertThat(context).hasSingleBean(PlatformTransactionManager.class); assertThat(context.getBean(PlatformTransactionManager.class).toString()) .contains("DataSourceTransactionManager"); - assertThat(context.getBean(BatchProperties.class).getInitializeSchema()) + assertThat(context.getBean(BatchProperties.class).getJdbc().getInitializeSchema()) .isEqualTo(DataSourceInitializationMode.EMBEDDED); assertThat(new JdbcTemplate(context.getBean(DataSource.class)) .queryForList("select * from BATCH_JOB_EXECUTION")).isEmpty(); @@ -71,17 +73,30 @@ class BatchAutoConfigurationWithoutJpaTests { @Test void jdbcWithCustomPrefix() { + this.contextRunner.withUserConfiguration(DefaultConfiguration.class, EmbeddedDataSourceConfiguration.class) + .withPropertyValues("spring.datasource.generate-unique-name=true", + "spring.batch.jdbc.schema:classpath:batch/custom-schema-hsql.sql", + "spring.batch.jdbc.tablePrefix:PREFIX_") + .run(assertCustomPrefix()); + } + + @Test + @Deprecated + void jdbcWithCustomPrefixWithDeprecatedProperties() { this.contextRunner.withUserConfiguration(DefaultConfiguration.class, EmbeddedDataSourceConfiguration.class) .withPropertyValues("spring.datasource.generate-unique-name=true", "spring.batch.schema:classpath:batch/custom-schema-hsql.sql", "spring.batch.tablePrefix:PREFIX_") - .run((context) -> { - assertThat(new JdbcTemplate(context.getBean(DataSource.class)) - .queryForList("select * from PREFIX_JOB_EXECUTION")).isEmpty(); - assertThat(context.getBean(JobExplorer.class).findRunningJobExecutions("test")).isEmpty(); - assertThat(context.getBean(JobRepository.class).getLastJobExecution("test", new JobParameters())) - .isNull(); - }); + .run(assertCustomPrefix()); + } + + private ContextConsumer assertCustomPrefix() { + return (context) -> { + assertThat(new JdbcTemplate(context.getBean(DataSource.class)) + .queryForList("select * from PREFIX_JOB_EXECUTION")).isEmpty(); + assertThat(context.getBean(JobExplorer.class).findRunningJobExecutions("test")).isEmpty(); + assertThat(context.getBean(JobRepository.class).getLastJobExecution("test", new JobParameters())).isNull(); + }; } @EnableBatchProcessing diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto.adoc index 481c0762e2..7fff03eec2 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto.adoc @@ -2087,10 +2087,11 @@ You can also enable it for any database type, as shown in the following example: ---- spring: batch: - initialize-schema: "always" + jdbc: + initialize-schema: "always" ---- -You can also switch off the initialization explicitly by setting `spring.batch.initialize-schema` to `never`. +You can also switch off the initialization explicitly by setting `spring.batch.jdbc.initialize-schema` to `never`.