Reputation: 732
I had to upgrade my app to Spring Batch 5 as multiple classes were deprecated as a requirement to moving to Spring 3. However my JobRepository is now failing to start because of a null "this.incrementerFactory" is null. I tried using a default incrementerFactory but that throws an exception. Here is my configuration
Here is the application.yml
spring:
batch:
job:
enabled: true # set this to true if you want the batch job to start as soon as Spring loads
name: productFetchJob
jdbc:
initialize-schema: always
schema: schema-h2.sql
main:
allow-bean-definition-overriding: true
This portion is no longer supported and worked
jdbc:
datasource:
schema: schema-h2.sql
auto-commit: true
public class JobRepositoryConfig {
@Qualifier("jobMetaDataSource")
final DataSource jobMetaDataSource;
@Value("${processing.thread-pool-size}") int threadPoolSize;
@Bean("jobRepositoryTransactionManager")
PlatformTransactionManager jobRepositoryTransactionManager(@Qualifier("jobMetaDataSource") DataSource jobMetaDataSource){
return new DataSourceTransactionManager(jobMetaDataSource);
}
@Bean
public JobRepositoryFactoryBean jobRepositoryFactory(@Qualifier("jobRepositoryTransactionManager")PlatformTransactionManager jobRepositoryTransactionManager) throws Exception {
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(jobMetaDataSource);
var incrementerFactory = new DefaultDataFieldMaxValueIncrementerFactory(jobMetaDataSource);
factory.setTransactionManager(jobRepositoryTransactionManager);
factory.setIncrementerFactory(incrementerFactory);
factory.afterPropertiesSet();
return factory;
}
@Bean("productJobRepository")
public JobRepository productJobRepository(@Qualifier("jobRepositoryTransactionManager")PlatformTransactionManager jobRepositoryTransactionManager) throws Exception {
JobRepositoryFactoryBean jobRepositoryFactoryBean = new JobRepositoryFactoryBean();
jobRepositoryFactoryBean.setDataSource(jobMetaDataSource);
var incrementerFactory = new DefaultDataFieldMaxValueIncrementerFactory(jobMetaDataSource);
jobRepositoryFactoryBean.setTransactionManager(jobRepositoryTransactionManager);
jobRepositoryFactoryBean.setIncrementerFactory(incrementerFactory);
return jobRepositoryFactoryBean.getObject();
}
@Bean("productAppJobLauncher")
public JobLauncher productAppJobLauncher(@Qualifier("productJobRepository") JobRepository productJobRepository) {
TaskExecutorJobLauncher jobLauncher = new TaskExecutorJobLauncher();
jobLauncher.setTaskExecutor(jobLauncherTaskExecutor());
jobLauncher.setJobRepository(productJobRepository);
return jobLauncher;
}
@Bean("jobLauncherTaskExecutor")
public TaskExecutor jobLauncherTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setMaxPoolSize(threadPoolSize);
executor.setCorePoolSize(threadPoolSize);
return executor;
}
}
Here is the exception
Failed to instantiate [org.springframework.batch.core.repository.JobRepository]: Factory method 'productJobRepository' threw exception with message: Cannot invoke "String.toUpperCase()" because "incrementerType" is null at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800) at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:245) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBe
I don't understand what I need to provide now other than this, can someone help?
Why would a design not make use of sensible defaults. If you can specify a database type the connection etc. why should a configuration break which used to work because of the setIncrementerFactory. When I created one, the next failure was,.that there was no conversion service, what? I simply gave up because it was quickly evident when looking at the implementation of the JobRepository, that a lot of upfront configuration was being done and that unless I added all those, it was going to be a losing battle. Like I said, I gave up and removed all the custom configuration and simply injected a JobRepository, how frustrating. JobBuilderFactory, StepBuilderFactory etc. why? These have been present all this while, I solved the problem otherwise.
The datasource property of jdbc has been removed. The schema can only be specified directly, but now it complains that it cannot find schema-h2.sql. Also, the auto-commit property has been removed, just frustrating all these features which have existed for years get changed and the replacement configurations just don't work. i dislike this about Spring and will use Quarkus or other more stable dependency injection frameworks in the future. Changing classes is one thing but when the new configurations don't work out of the box, that's a whole new different ball game.
This exception is thrown because spring cannot find the schema for the JobRepository database when it used to find it before under jdbc.datasource.schema in the spring.data attribute.
Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled. 2023-11-25T15:45:49.270-06:00 ERROR 27938 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'runController' defined in file [/Users/projects/catalog-product-batch/build/classes/java/main/com/inventory/product/batch/controller/RunController.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'productJobScheduler' defined in file [/Users/projects/catalog-product-batch/build/classes/java/main/com/inventory/product/batch/scheduler/ProductJobScheduler.class]: Unsatisfied dependency expressed through constructor parameter 3: Error creating bean with name 'ProductJobConfig' defined in file [/Users/projects/catalog-product-batch/build/classes/java/main/com/inventory/product/batch/job/ProductJobConfig.class]: Unsatisfied dependency expressed through constructor parameter 2: Error creating bean with name 'updateProductsStep' defined in file [/Users/projects/catalog-product-batch/build/classes/java/main/com/inventory/product/batch/step/data/UpdateProductsStep.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'batchDataSourceProductizer' defined in class path resource [org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration$DataSourceProductizerConfiguration.class]: No schema scripts found at product 'schema-h2.sql' at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800) at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:245) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1352) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1189) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:560) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:973) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryproductization(AbstractApplicationContext.java:942) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:608) at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:436) at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) at com.inventory.product.batch.productBatchApplication.main(ProductBatchApplication.java:25) Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'productJobScheduler' defined in file [/Users/projects/catalog-product-batch/build/classes/java/main/com/inventory/product/batch/scheduler/ProductJobScheduler.class]: Unsatisfied dependency expressed through constructor parameter 3: Error creating bean with name 'productJobConfig' defined in file [/Users/projects/catalog-product-batch/build/classes/java/main/com/inventory/product/batch/job/ProductJobConfig.class]: Unsatisfied dependency expressed through constructor parameter 2: Error creating bean with name 'updateProductsStep' defined in file [/Users/projects/catalog-product-batch/build/classes/java/main/com/inventory/product/batch/step/data/UpdateProductsStep.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'batchDataSourceproductizer' defined in class path resource [org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration$DataSourceproductizerConfiguration.class]: No schema scripts found at product 'schema-h2.sql' at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800) at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:245) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1352) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1189) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:560) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1417) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1337) at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:888) at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ... 19 common frames omitted Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'productJobConfig' defined in file [/Users/projects/catalog-product-batch/build/classes/java/main/com/inventory/product/batch/job/ProductJobConfig.class]: Unsatisfied dependency expressed through constructor parameter 2: Error creating bean with name 'updateProductsStep' defined in file [/Users/projects/catalog-product-batch/build/classes/java/main/com/inventory/product/batch/step/data/UpdateProductsStep.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'batchDataSourceproductizer' defined in class path resource [org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration$DataSourceproductizerConfiguration.class]: No schema scripts found at product 'schema-h2.sql' at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800) at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:245) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1352) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1189) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:560) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:417) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1332) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1162) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:560) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1417) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1337) at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:888) at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ... 33 common frames omitted Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'updateProductsStep' defined in file [/Users/projects/catalog-product-batch/build/classes/java/main/com/inventory/product/batch/step/data/UpdateProductsStep.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'batchDataSourceProductizer' defined in class path resource [org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration$DataSourceProductizerConfiguration.class]: No schema scripts found at product 'schema-h2.sql' at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800) at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:245) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1352) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1189) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:560) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:417) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1332) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1162) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:560) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1417) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1337) at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:888) at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ... 56 common frames omitted Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'batchDataSourceProductizer' defined in class path resource [org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration$DataSourceProductizerConfiguration.class]: No schema scripts found at product 'schema-h2.sql' at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.productizeBean(AbstractAutowireCapableBeanFactory.java:1770) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:598) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:313) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1417) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1337) at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:888) at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ... 79 common frames omitted Caused by: java.lang.IllegalStateException: No schema scripts found at product 'schema-h2.sql' at org.springframework.boot.sql.init.AbstractScriptDatabaseproductizer.getScripts(AbstractScriptDatabaseproductizer.java:129) at org.springframework.boot.sql.init.AbstractScriptDatabaseproductizer.applyScripts(AbstractScriptDatabaseproductizer.java:106) at org.springframework.boot.sql.init.AbstractScriptDatabaseproductizer.applySchemaScripts(AbstractScriptDatabaseproductizer.java:98) at org.springframework.boot.sql.init.AbstractScriptDatabaseproductizer.productizeDatabase(AbstractScriptDatabaseproductizer.java:76) at org.springframework.boot.sql.init.AbstractScriptDatabaseproductizer.afterPropertiesSet(AbstractScriptDatabaseproductizer.java:66) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1817) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.productizeBean(AbstractAutowireCapableBeanFactory.java:1766) ... 92 common frames omitted
Task :bootRun FAILED
FAILURE: Build failed with an exception.
Upvotes: 1
Views: 10592
Reputation: 141
I started going down the rabbit hole of defining everything that it needed, like for example the IncrementerFactory, the ConversionService etc, and then I later realized that all of that could be replaced by adding:
jobRepositoryFactoryBean.afterPropertiesSet();
After setting all the necessary properties, which would look like this:
var jobRepositoryFactoryBean = new JobRepositoryFactoryBean();
jobRepositoryFactoryBean.setDataSource(dataSource);
jobRepositoryFactoryBean.setTransactionManager(transactionManager);
jobRepositoryFactoryBean.afterPropertiesSet();
return jobRepositoryFactoryBean.getObject();
Upvotes: 2
Reputation: 31640
Error creating bean with name 'batchDataSourceProductizer' defined in class path resource [org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration$DataSourceProductizerConfiguration.class]: No schema scripts found at product 'schema-h2.sql'
I tried to reproduce this issue with what you shared and this error comes from an incorrect value in the properties file here spring.batch.jdbc.schema=schema-h2.sql
. That property can be either omitted (in which case Spring Boot will default to classpath:org/springframework/batch/core/schema-@@platform@@.sql
) or set to the full path of the initialization script like: spring.batch.jdbc.schema=/org/springframework/batch/core/schema-h2.sql
). Passing only the script file name is not enough (and which could be the cause of the incrementer factory issue, which could not be inferred).
No I'm not. I am aware and removed @EnableBatchProcessing so that autoconfiguration will work in Spring 3. The problem has nothing to do with that. The problem is that I am mandated to provide an incrementerFactory, and subsequently a ConversionService, you see the problem? Prior to Spring Batch 5, my configuration only provided only a datasource and JdbcTemplate and that was fine. In a nutshell, Spring Batch 5 does not support the minimal configuration.
Here is a minimal complete example with a datasource and jdbc template:
File src/main/java/com/example/demo/DemoApplication.java
:
package com.example.demo;
import javax.sql.DataSource;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.job.builder.JobBuilder;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.jdbc.support.JdbcTransactionManager;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
public Job job(JobRepository jobRepository, JdbcTransactionManager batchTransactionManager, JdbcTemplate batchJdbcTemplate) {
return new JobBuilder("job", jobRepository)
.start(new StepBuilder("step", jobRepository)
.tasklet((contribution, chunkContext) -> {
System.out.println("Nb persons: " + batchJdbcTemplate.queryForObject("select count(*) from persons", Integer.class));
System.out.println("Nb job instances: " + batchJdbcTemplate.queryForObject("select count(*) from BATCH_JOB_INSTANCE", Integer.class));
return RepeatStatus.FINISHED;
}, batchTransactionManager)
.build())
.build();
}
@Bean
public DataSource batchDataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.addScript("/org/springframework/batch/core/schema-h2.sql")
.addScript("/persons.sql")
.build();
}
@Bean
public JdbcTransactionManager batchTransactionManager(DataSource batchDataSource) {
return new JdbcTransactionManager(batchDataSource);
}
@Bean
public JdbcTemplate batchJdbcTemplate(DataSource batchDataSource) {
return new JdbcTemplate(batchDataSource);
}
}
File pom.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>21</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
File resources/persons.sql
create table persons (id int primary key, name varchar);
insert into persons values (1, 'foo');
insert into persons values (2, 'bar');
File resources/application.properties
: empty
If you run this app, it prints:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.2.0)
2023-12-04T15:03:12.645+01:00 INFO 70973 --- [ main] com.example.demo.DemoApplication : Starting DemoApplication using Java 21-ea with PID 70973 (/tmp/so77530727/target/classes started by XXX in /tmp/so77530727)
2023-12-04T15:03:12.650+01:00 INFO 70973 --- [ main] com.example.demo.DemoApplication : No active profile set, falling back to 1 default profile: "default"
2023-12-04T15:03:13.202+01:00 WARN 70973 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'demoApplication' of type [com.example.demo.DemoApplication$$SpringCGLIB$$0] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [jobRegistryBeanPostProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies.
2023-12-04T15:03:13.221+01:00 INFO 70973 --- [ main] o.s.j.d.e.EmbeddedDatabaseFactory : Starting embedded database: url='jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false', username='sa'
2023-12-04T15:03:13.464+01:00 WARN 70973 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'batchDataSource' of type [org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactory$EmbeddedDataSourceProxy] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [jobRegistryBeanPostProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies.
2023-12-04T15:03:13.470+01:00 WARN 70973 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'batchTransactionManager' of type [org.springframework.jdbc.support.JdbcTransactionManager] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [jobRegistryBeanPostProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies.
2023-12-04T15:03:13.479+01:00 WARN 70973 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'spring.batch-org.springframework.boot.autoconfigure.batch.BatchProperties' of type [org.springframework.boot.autoconfigure.batch.BatchProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [jobRegistryBeanPostProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies.
2023-12-04T15:03:13.484+01:00 WARN 70973 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration$SpringBootBatchConfiguration' of type [org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration$SpringBootBatchConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). The currently created BeanPostProcessor [jobRegistryBeanPostProcessor] is declared through a non-static factory method on that class; consider declaring it as static instead.
2023-12-04T15:03:13.671+01:00 INFO 70973 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 1.5 seconds (process running for 2.19)
2023-12-04T15:03:13.673+01:00 INFO 70973 --- [ main] o.s.b.a.b.JobLauncherApplicationRunner : Running default command line with: []
2023-12-04T15:03:13.699+01:00 INFO 70973 --- [ main] o.s.b.c.l.support.SimpleJobLauncher : Job: [SimpleJob: [name=job]] launched with the following parameters: [{}]
2023-12-04T15:03:13.727+01:00 INFO 70973 --- [ main] o.s.batch.core.job.SimpleStepHandler : Executing step: [step]
Nb persons: 2
Nb job instances: 1
2023-12-04T15:03:13.736+01:00 INFO 70973 --- [ main] o.s.batch.core.step.AbstractStep : Step: [step] executed in 9ms
2023-12-04T15:03:13.742+01:00 INFO 70973 --- [ main] o.s.b.c.l.support.SimpleJobLauncher : Job: [SimpleJob: [name=job]] completed with the following parameters: [{}] and the following status: [COMPLETED] in 28ms
2023-12-04T15:03:13.747+01:00 INFO 70973 --- [ionShutdownHook] o.s.j.d.e.EmbeddedDatabaseFactory : Shutting down embedded database: url='jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false'
As a batch user, I provided the custom batch datasource and jdbc template, which were used by the job and job repository, but I was not mandated to provide an incrementerFactory.
Upvotes: 1