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.
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. – Pogey