0
votes

I'm trying to setup a spring boot batch project that uses a ResourcelessTransactionManager transaction manager using Java Configuration, but I'm having no luck.

The reason I am trying to do this is that I don't want any state persisted, and I'd prefer not to waste memory with hsqldb if I don't want it to begin with. I have an existing Spring Batch project that is not using Spring Boot, and it is working with no persistance and without hsqldb.

I'm using this sample project as the base (but with hsqldb removed), and this other answer as a reference but I keep getting this exception:

Caused by: org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active).
    at org.springframework.boot.autoconfigure.jdbc.DataSourceProperties.determineDriverClassName(DataSourceProperties.java:218) ~[spring-boot-autoconfigure-1.4.0.RELEASE.jar:1.4.0.RELEASE]
    at org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration.createDataSource(DataSourceConfiguration.java:42) ~[spring-boot-autoconfigure-1.4.0.RELEASE.jar:1.4.0.RELEASE]
    at org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Tomcat.dataSource(DataSourceConfiguration.java:55) ~[spring-boot-autoconfigure-1.4.0.RELEASE.jar:1.4.0.RELEASE]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_73]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_73]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_73]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_73]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    ... 56 common frames omitted

This is what I modified:

@SpringBootApplication
@EnableBatchProcessing
@Configuration
public class SampleBatchApplication {

    @Autowired
    private JobBuilderFactory jobs;

    @Autowired
    private StepBuilderFactory steps;

    @Bean
    protected Tasklet tasklet() {

        return new Tasklet() {
            @Override
            public RepeatStatus execute(StepContribution contribution,
                    ChunkContext context) {
                return RepeatStatus.FINISHED;
            }
        };

    }

    @Bean
    public Job job() throws Exception {
        return this.jobs.get("job").start(step1()).build();
    }

    @Bean
    protected Step step1() throws Exception {
        return this.steps.get("step1").tasklet(tasklet()).build();
    }


    public static void main(String[] args) throws Exception {
        // System.exit is common for Batch applications since the exit code can be used to
        // drive a workflow
        System.exit(SpringApplication
                .exit(SpringApplication.run(SampleBatchApplication.class, args)));
    }

    @Bean
    ResourcelessTransactionManager transactionManager() {
        return new ResourcelessTransactionManager();
    }

    @Bean
    public JobRepository getJobRepo() throws Exception {
        return new MapJobRepositoryFactoryBean(transactionManager()).getObject();
    }

}

What do I need to do to make it use the ResourcelessTransactionManager?

EDIT: Added clarity around why I want the ResourcelessTransactionManager to work.

2

2 Answers

0
votes

Below are some basic spring boot properties to set up data sources. By looking at driver class , boot can infer your db type and can auto create DataSource bean.

spring.datasource.driver-class-name
spring.datasource.url
spring.datasource.username
spring.datasource.password
spring.datasource.tomcat.max-active
spring.datasource.tomcat.initialSize
spring.datasource.tomcat.maxIdle

Last three properties are for setting up connection pools in container. Explicit DataSource information is missing and no in-memory database is provided in classpath.

Fix issue by explicitly providing entries in application.properties or by including in-memory db ( H2 , HSQL etc ) in class path.

Your configuration looks OK for not using any data sources ( i.e. if you have configured ResourcelessTransactionManager & MapJobRepository ) as long as you don't use EnableAutoConfiguration but your stack trace indicates usage of Boot with EnableAutoConfiguration.

I guess, selective disabling of data source is not allowed, see question

EDIT: I was able to fix error in your code by adding @SpringBootApplication(exclude={DataSource.class,DataSourceAutoConfiguration.class})

Logs dumped this - after bean creation process,

Exclusions:

org.apache.tomcat.jdbc.pool.DataSource

org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
0
votes

Your problem seem to be no data source available in your configuration. Spring Batch needs database so persist its state.

Spring Boot can automatically configure in memory DB if you have some on classpath. Example application you are referring to has HSQL included in POM here: https://github.com/spring-projects/spring-boot/blob/v1.4.0.RELEASE/spring-boot-samples/spring-boot-sample-batch/pom.xml#L26

So to fix your problem, define access to your Database.