8

I am writing a test case to test my Step in spring batch. Below is my configuration

@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {BatchTemplateConfig.class,
        CustomerItemWriter.class,BatchAutoConfiguration.class})
@JdbcTest
@EnableBatchProcessing
@SpringBatchTest
public class SampleStepTest {
    @Autowired
    private JobLauncherTestUtils jobLauncherTestUtils;
    @Test
   public void testSampleStep(){
        JobExecution jobExecution = this.jobLauncherTestUtils.launchStep("sampleStep");
        assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus());

    }
}

Below is my step configuration

 @Bean
    public Step sampleStep(JobRepository jobRepository, PlatformTransactionManager transactionManager, ItemWriter<Customer> itemWriter, ItemReader<Customer> itemReader) {
        return new StepBuilder("sampleStep", jobRepository)
                .<Customer, Customer>chunk(1, transactionManager)
                .reader(itemReader)
                .writer(itemWriter)
                .build();
    }

I have tried disabling @EnableSpringBatchProcessing(since from spring boot 3, this is not required) and also tried to set the properties spring.batch.jdbc.initialize-schema=always also changed it to spring.batch.jdbc.initialize-schema=never by following this post. But still I am getting error like below.

2023-03-02T16:56:33.198+05:30  INFO 5288 --- [    Test worker] s.g.b.s.SampleStepTest                   : Starting SampleStepTest using Java 17.0.6 with PID 5288 (started by  INFO 5288 --- [    Test worker] s.g.b.s.SampleStepTest                   : No active profile set, falling back to 1 default profile: "default"
2023-03-02T16:56:34.277+05:30  INFO 5288 --- [    Test worker] o.s.b.c.c.annotation.BatchRegistrar      : Finished Spring Batch infrastructure beans configuration in 13 ms.
2023-03-02T16:56:34.558+05:30  INFO 5288 --- [    Test worker] beddedDataSourceBeanFactoryPostProcessor : Replacing 'dataSource' DataSource bean with embedded version
2023-03-02T16:56:35.048+05:30  INFO 5288 --- [    Test worker] o.s.j.d.e.EmbeddedDatabaseFactory        : Starting embedded database: url='jdbc:h2:mem:e71d89d7-9684-47e3-9a70-c90803db19d9;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false', username='sa'
2023-03-02T16:56:36.061+05:30  INFO 5288 --- [    Test worker] o.s.b.c.r.s.JobRepositoryFactoryBean     : No database type set, using meta data indicating: H2
2023-03-02T16:56:36.491+05:30  INFO 5288 --- [    Test worker] .c.a.BatchObservabilityBeanPostProcessor : No Micrometer observation registry found, defaulting to ObservationRegistry.NOOP
2023-03-02T16:56:36.544+05:30  INFO 5288 --- [    Test worker] .c.a.BatchObservabilityBeanPostProcessor : No Micrometer observation registry found, defaulting to ObservationRegistry.NOOP
2023-03-02T16:56:36.550+05:30  INFO 5288 --- [    Test worker] o.s.b.c.l.support.SimpleJobLauncher      : No TaskExecutor has been set, defaulting to synchronous executor.
2023-03-02T16:56:36.709+05:30  INFO 5288 --- [    Test worker] s.g.b.s.SampleStepTest                   : Started SampleStepTest in 7.266 seconds (process running for 11.933)

PreparedStatementCallback; bad SQL grammar [SELECT JOB_INSTANCE_ID, JOB_NAME from BATCH_JOB_INSTANCE where JOB_NAME = ? and JOB_KEY = ?]
org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [SELECT JOB_INSTANCE_ID, JOB_NAME from BATCH_JOB_INSTANCE where JOB_NAME = ? and JOB_KEY = ?]
    at app//org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:101)
    at app//org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:70)
    at app//org.springframework.jdbc.core.JdbcTemplate.translateException(JdbcTemplate.java:1538)
    at app//org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:667)
    at app//org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:713)
    at app//org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:744)
    at app//org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:757)
    at app//org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:815)
    at app//org.springframework.batch.core.repository.dao.JdbcJobInstanceDao.getJobInstance(JdbcJobInstanceDao.java:143)
    at app//org.springframework.batch.core.repository.support.SimpleJobRepository.getLastJobExecution(SimpleJobRepository.java:299)
    at [email protected]/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at [email protected]/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at [email protected]/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at [email protected]/java.lang.reflect.Method.invoke(Method.java:568)
    at app//org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343)
    at app//org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196)
    at app//org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at app//org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
    at app//org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:390)
    at app//org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
    at app//org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
    at app//org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:218)
    at app/jdk.proxy3/jdk.proxy3.$Proxy61.getLastJobExecution(Unknown Source)
    at app//org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:111)
    at app//org.springframework.batch.core.launch.support.TaskExecutorJobLauncher.run(TaskExecutorJobLauncher.java:70)
    at app//org.springframework.batch.test.StepRunner.launchJob(StepRunner.java:167)
    at app//org.springframework.batch.test.StepRunner.launchStep(StepRunner.java:157)
    at app//org.springframework.batch.test.JobLauncherTestUtils.launchStep(JobLauncherTestUtils.java:237)
    at app//org.springframework.batch.test.JobLauncherTestUtils.launchStep(JobLauncherTestUtils.java:187)
    at app//sg.gov.br2s.springbatchtemplate.SampleStepTest.testSampleStep(SampleStepTest.java:37)
    at [email protected]/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at [email protected]/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at [email protected]/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at [email protected]/java.lang.reflect.Method.invoke(Method.java:568)
    at app//org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:727)
    at app//org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
    at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
    at app//org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156)
    at app//org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147)
    at app//org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86)
    at app//org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103)
    at app//org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93)
    at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
    at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
    at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
    at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
    at app//org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92)
    at app//org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86)
    at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:217)
    at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:213)
    at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:138)
    at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68)
    at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
    at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    at app//org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    at [email protected]/java.util.ArrayList.forEach(ArrayList.java:1511)
    at app//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
    at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
    at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    at app//org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    at [email protected]/java.util.ArrayList.forEach(ArrayList.java:1511)
    at app//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
    at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
    at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    at app//org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    at app//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
    at app//org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
    at app//org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
    at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
    at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:99)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62)
    at [email protected]/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at [email protected]/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at [email protected]/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at [email protected]/java.lang.reflect.Method.invoke(Method.java:568)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
    at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
    at jdk.proxy2/jdk.proxy2.$Proxy5.stop(Unknown Source)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
    at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
    at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113)
    at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65)
    at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
    at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "BATCH_JOB_INSTANCE" not found (this database is empty); SQL statement:
SELECT JOB_INSTANCE_ID, JOB_NAME from BATCH_JOB_INSTANCE where JOB_NAME = ? and JOB_KEY = ? [42104-214]
    at app//org.h2.message.DbException.getJdbcSQLException(DbException.java:502)
    at app//org.h2.message.DbException.getJdbcSQLException(DbException.java:477)
    at app//org.h2.message.DbException.get(DbException.java:223)
    at app//org.h2.message.DbException.get(DbException.java:199)
    at app//org.h2.command.Parser.getTableOrViewNotFoundDbException(Parser.java:8385)
    at app//org.h2.command.Parser.getTableOrViewNotFoundDbException(Parser.java:8369)
    at app//org.h2.command.Parser.readTableOrView(Parser.java:8358)
    at app//org.h2.command.Parser.readTablePrimary(Parser.java:1863)
    at app//org.h2.command.Parser.readTableReference(Parser.java:2334)
    at app//org.h2.command.Parser.parseSelectFromPart(Parser.java:2772)
    at app//org.h2.command.Parser.parseSelect(Parser.java:2878)
    at app//org.h2.command.Parser.parseQueryPrimary(Parser.java:2762)
    at app//org.h2.command.Parser.parseQueryTerm(Parser.java:2633)
    at app//org.h2.command.Parser.parseQueryExpressionBody(Parser.java:2612)
    at app//org.h2.command.Parser.parseQueryExpressionBodyAndEndOfQuery(Parser.java:2605)
    at app//org.h2.command.Parser.parseQueryExpression(Parser.java:2598)
    at app//org.h2.command.Parser.parseQuery(Parser.java:2567)
    at app//org.h2.command.Parser.parsePrepared(Parser.java:724)
    at app//org.h2.command.Parser.parse(Parser.java:689)
    at app//org.h2.command.Parser.parse(Parser.java:661)
    at app//org.h2.command.Parser.prepareCommand(Parser.java:569)
    at app//org.h2.engine.SessionLocal.prepareLocal(SessionLocal.java:631)
    at app//org.h2.engine.SessionLocal.prepareCommand(SessionLocal.java:554)
    at app//org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1116)
    at app//org.h2.jdbc.JdbcPreparedStatement.<init>(JdbcPreparedStatement.java:92)
    at app//org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:288)
    at app//org.springframework.jdbc.core.JdbcTemplate$SimplePreparedStatementCreator.createPreparedStatement(JdbcTemplate.java:1637)
    at app//org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:649)
    ... 111 more

When I try to disable @EnableBatchProcessing I am getting a different error

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of method sampleJob in com.example.springbatchtemplate.config.BatchTemplateConfig required a bean of type 'org.springframework.batch.core.repository.JobRepository' that could not be found.


Action:

Consider defining a bean of type 'org.springframework.batch.core.repository.JobRepository' in your configuration.
5
  • You did not share your datasource configuration.Please share a complete example with a stack trace of the error. Commented Mar 2, 2023 at 12:22
  • It seems you are missing the required tables for batch in your test datasource Commented Mar 2, 2023 at 12:24
  • @Mahmoud Ben Hassine yes it is an embedded data source . I have not made any configurations. But unit tests for my item reader works fine without any configurations.Should I share my reader and writer configs also?I have update the error message with stack trace Commented Mar 2, 2023 at 12:34
  • I have tried disabling @EnableSpringBatchProcessing(since from spring boot 3, this is not required): The code above still has that annotation. Are you sure the issue still happens without @EnableBatchProcessing? Because with @EnableBatchProcessing, Spring Boot v3 will not auto-configure the batch tables. Commented Mar 2, 2023 at 12:42
  • When I am disabling the @EnableBatchProcessing I am getting a different error altogether. Tried it just now Commented Mar 2, 2023 at 12:47

4 Answers 4

6

From Batch 5, When @EnableBatchProcessing is used, the jobLauncherApplicationRunner bean is not created in BatchAutoConfiguration.java That is because @ConditionalOnMissingBean is added in version 5.

...
@ConditionalOnMissingBean(value = DefaultBatchConfiguration.class, annotation = EnableBatchProcessing.class)
....
public class BatchAutoConfiguration {

But @EnableBatchProcessing should be used to set other datasource and transacionmanager for JobRepository.

Likewise, BatchDataSourceScriptDatabaseInitializer, which initializes data schema, is not created.
As solution, We can create the bean by ourselves.

@Configuration
@EnableConfigurationProperties(BatchProperties.class)
public class BatchConfig {

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(prefix = "spring.batch.job", name = "enabled", havingValue = "true", matchIfMissing = true)
    public JobLauncherApplicationRunner jobLauncherApplicationRunner(
            JobLauncher jobLauncher, JobExplorer jobExplorer, JobRepository jobRepository, BatchProperties properties) {
        JobLauncherApplicationRunner runner =
                new JobLauncherApplicationRunner(jobLauncher, jobExplorer, jobRepository);
        String jobNames = properties.getJob().getName();
        if (StringUtils.hasText(jobNames)) {
            runner.setJobName(jobNames);
        }
        return runner;
    }
}

    @Bean
    @ConditionalOnMissingBean(BatchDataSourceScriptDatabaseInitializer.class)
    BatchDataSourceScriptDatabaseInitializer batchDataSourceInitializer(DataSource dataSource,
                @BatchDataSource ObjectProvider<DataSource> batchDataSource, BatchProperties properties) {
            return new BatchDataSourceScriptDatabaseInitializer(batchDataSource.getIfAvailable(() -> dataSource),
                    properties.getJdbc());
    }
Sign up to request clarification or add additional context in comments.

2 Comments

Works, but it is crazy that now we have to care about this, as @EnableBatchProcessing use is discouraged.
this answer really saved us.
3

You need to add a correct datasource and scripts to populate your DB. Something like in your BatchTemplateConfig class:

@Bean(name = "dataSource")
public DataSource dataSource() {
    EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
    return builder.setType(EmbeddedDatabaseType.HSQL)
      .addScript("classpath:org/springframework/batch/core/schema-drop-hsqldb.sql")
      .addScript("classpath:org/springframework/batch/core/schema-hsqldb.sql")
      .build();
}

Comments

2

If you are using Spring-Batch 5 and Spring boot 3 and having the annotation @EnableBatchProcessing, then the tables are not created. If you remove @EnableBatchProcessing annotation, then the tables are created.

So this setup, will not create the tables:

@EnableBatchProcessing
@SpringBootApplication

Ref: https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.0-Migration-Guide#spring-batch-changes

Comments

1

I had a similar error as the OP, I'm on Spring framework 5.0, boot 3.0

I removed the annotation @EnableBatchProcessing(dataSourceRef = "mssqlDataSource", transactionManagerRef = "mssqlTransactionManager")

My datasource is configured as a bean elsewhere, but as mentioned by @tasosioan7 it must be configured

Here is my properties for the integration test:

spring:
  batch:
    jdbc:
      initialize-schema: always
      platform: h2
    job:
      enabled: false
  datasource:
    url: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS Schema
    username: sa
    password:
    driver-class-name: org.h2.Driver
    hikari:
      poolName: ReadHikariPool
      schema: Schema
  jpa:
    database: h2
    generate-ddl: true
    show-sql: true
    database-platform: org.hibernate.dialect.H2Dialect

Here is most of my very basic test

@SpringBatchTest
@SpringBootTest
@EnableAutoConfiguration
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,
        DirtiesContextTestExecutionListener.class})
@DirtiesContext
@ActiveProfiles("itest")
public class BatchTest {

    @Autowired
    DataSource mssqlDataSource;

    @Autowired
    private JobLauncherTestUtils jobLauncherTestUtils;

    @Autowired
    private JobRepositoryTestUtils jobRepositoryTestUtils;

    @Autowired
    private DataRepository dataRepository;

    @AfterEach
    public void cleanUp() {
        jobRepositoryTestUtils.removeJobExecutions();
    }

    @Test
    public void given_whenStep1Executed_thenSuccess() throws Exception {
        // given

        // when
        JobExecution jobExecution = jobLauncherTestUtils.launchStep(
                "readLastRow");
        Collection actualStepExecutions = jobExecution.getStepExecutions();
        ExitStatus actualJobExitStatus = jobExecution.getExitStatus();

        // then
        assertThat(actualStepExecutions.size(), is(1));
        assertThat(actualJobExitStatus.getExitCode(), is("COMPLETED"));
    }
}

1 Comment

Removing the @EnableBatchProcessing annotation also worked for me while having the database configuration set in the properties file.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.