user1500300
user1500300

Reputation: 67

Spring Batch 5 is not autocreating table in H2 database

I've created a simple Spring Batch application using H2 database and gradle. Version of Spring Boot is 3.0.4. There is only one job and only one step that reads from csv file and logs into the console. I've already set the flag spring.batch.initialize-schema=always which should have happened anyways when using embedded databases. I've created a rest controller to trigger the start of the job but getting the error below:

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 org.h2.message.DbException.getJdbcSQLException(DbException.java:502) ~[h2-2.1.214.jar:2.1.214] at org.h2.message.DbException.getJdbcSQLException(DbException.java:477) ~[h2-2.1.214.jar:2.1.214] at org.h2.message.DbException.get(DbException.java:223) ~[h2-2.1.214.jar:2.1.214] at org.h2.message.DbException.get(DbException.java:199) ~[h2-2.1.214.jar:2.1.214]

Not sure if there's some extra config needed for H2 database for Spring Boot 3. Below are some code snippets that might be of relevance:

application.properties

spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect

spring.batch.initialize-schema=always

Config file for Spring Batch:

    @Bean
    public Job importUserJob(JobRepository jobRepository,
                             JobCompletionNotificationListener listener, Step step1) {
        return new JobBuilder("importUserJob", jobRepository)
                .incrementer(new RunIdIncrementer())
                .listener(listener)
                .flow(step1)
                .end()
                .build();
    }

    @Bean
    public Step step1(JobRepository jobRepository,
                      PlatformTransactionManager transactionManager, ItemWriter<Person> writer) {
        return new StepBuilder("step1", jobRepository)
                .<Person, Person> chunk(10, transactionManager)
                .reader(reader())
                .processor(processor())
                .writer(writer)
                .build();
    }

    @Bean
    public FlatFileItemReader<Person> reader() {
        log.info("FlatFileItemReader instance");
        return new FlatFileItemReaderBuilder<Person>()
                .name("personItemReader")
                .resource(new ClassPathResource("something.csv"))
                .delimited()
                .names("firstName", "lastName")
                .fieldSetMapper(new BeanWrapperFieldSetMapper<Person>() {{
                    setTargetType(Person.class);
                }})
                .build();
    }

    @Bean
    public PersonItemProcessor processor() {
        return new PersonItemProcessor();
    }

    @Bean
    public ItemWriter<Person> writer() {
        return items -> {
            for (Person item : items) {
                System.out.println(item.toString());
            }
        };
    }

build.gradle

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.0.4'
    id 'io.spring.dependency-management' version '1.1.0'
}

group = 'com.springbatchtest'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-batch'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'com.h2database:h2'
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

Thanks much!

I've tried creating a Spring Batch application using the latest Spring Boot version 3. I expected the automatic creation of the tables when using embedded databases as detailed here: https://docs.spring.io/spring-boot/docs/2.0.0.M7/reference/htmlsingle/#howto-initialize-a-spring-batch-database.

Instead I got an error saying the tables don't exist

Upvotes: 4

Views: 5521

Answers (2)

Henning
Henning

Reputation: 3889

As of Spring Boot 3, the annotation @EnableBatchProcessing will disable Spring Boot's auto-configuration for Batch. It is this auto-configuration that creates the tables. Thus, you need to remove the annotation from your code.

The auto-configuration also starts jobs on start-up of the application. If you want to disable this particular feature, you can set the property spring.batch.job.enabled to false.

Upvotes: 4

John Williams
John Williams

Reputation: 5385

Try the following application property:

spring.jpa.hibernate.ddl-auto= update

Upvotes: 1

Related Questions