MuhammedH
MuhammedH

Reputation: 402

Spring boot app restart after spring batch job complete

I have spring boot app which should export a table in the database (product) as csv file so I am using spring batch to do that, my problem is that, when the job complete the app is restarted I think it is because spring batch close the entity manager after finish but I am not sure

note 1: I am using JpaPagingItemReader as reader.

note 2: I am starting the job from controller using JobLuncher

note 3: I know that the batch processing is working async so the controller return result before the job complete, i hope to find way to change this too.

note 4: I stopped the auto lunch of jobs using spring.batch.job.enabled=false in my application properties

note 5: I found a question for similar issue but it has no answer and closed (duplicated) but it is not and that was different problem.

my code:

-batch config:

    @Configuration
    public class BatchConfig {

    @Autowired
    private JobBuilderFactory jobBuilderFactory;
    @Autowired
    private StepBuilderFactory stepBuilderFactory;
    @PersistenceUnit
    EntityManagerFactory entityManagerFactory;

    @Bean
    public JpaPagingItemReader<Product> reader() {
        JpaPagingItemReader<Product> ir = new JpaPagingItemReaderBuilder<Product>().name("productReader")
                .entityManagerFactory(entityManagerFactory).queryString("select p from Product p").pageSize(500)
                .build();
        return ir;
    }

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

    @Bean
    public FlatFileItemWriter<Product> writer() {
        DelimitedLineAggregator<Product> aggregator = new DelimitedLineAggregator<Product>();
        BeanWrapperFieldExtractor<Product>  extractor = new BeanWrapperFieldExtractor<>();
        extractor.setNames(new String[] { "id", "name", "price" });
        aggregator.setFieldExtractor(extractor);

        FlatFileItemWriter<Product> writer = new FlatFileItemWriter<Product>();
        writer.setResource(new ClassPathResource("prices.csv"));
        writer.setLineAggregator(aggregator);

        return writer;
    }

     @Bean
     public Step step1() {
      return stepBuilderFactory.get("step1").<Product, Product> chunk(100)
        .reader(reader())
        .processor(processor())
        .writer(writer())
        .build();
     }

     @Bean
     public Job exportUserJob() {
      return jobBuilderFactory.get("exportUserJob")
        .incrementer(new RunIdIncrementer())
        .flow(step1())
        .end()
        .build();
     }


    }

-controller:

    @Autowired
    JobLauncher jobLauncher;

    @Autowired
    Job job;

    @RequestMapping("/test")
    @ResponseBody
    public String test(HttpSession session) {
        try {
            JobParameters jobParameters = new JobParametersBuilder().addLong("time", System.currentTimeMillis())
                    .toJobParameters();
            jobLauncher.run(job, jobParameters);
        } catch (Exception e) {
        System.out.println(e.getMessage());
        }

        return "Done";

    }

this is the console: console

after job complete with:

2020-01-06 14:02:03.570  INFO 4456 --- [nio-8080-exec-9] o.s.b.c.l.support.SimpleJobLauncher      : Job: [FlowJob: [name=exportUserJob]] completed with the following parameters: [{time=1578312121885}] and the following status: [COMPLETED]

it shut down and close the jpa:

2020-01-06 14:02:04.911  INFO 4456 --- [       Thread-7] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'
2020-01-06 14:02:04.918  INFO 4456 --- [       Thread-7] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2020-01-06 14:02:04.955  INFO 4456 --- [       Thread-7] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
2020-01-06 14:02:04.989  INFO 4456 --- [       Thread-7] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.

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>2.1.7.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.co-mada</groupId>
    <artifactId>Mada_Website</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>Mada_Website</name>
    <description>Mada Company Website</description>
    <!-- Packaging -->
    <packaging>war</packaging>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</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.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>


        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity5</artifactId>
            <!-- <version>3.0.4.RELEASE</version> -->
        </dependency>


        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.4.1</version>
        </dependency>


        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>4.3.1</version>
        </dependency>


        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>font-awesome</artifactId>
            <version>5.10.1</version>
        </dependency>


        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>popper.js</artifactId>
            <version>1.15.0</version>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
            <scope>runtime</scope>
        </dependency>



        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-search-orm</artifactId>
            <version>5.11.0.Final</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-jdbc</artifactId>
        </dependency>

        <!-- spring batch dependency -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-batch</artifactId>
        </dependency>


    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

main class:


@SpringBootApplication
@EnableBatchProcessing
public class MadaWebsiteApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(MadaWebsiteApplication.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        // TODO Auto-generated method stub
        return builder.sources(MadaWebsiteApplication.class);
    }


}

i hope everything clear, thanks.

Upvotes: 2

Views: 1253

Answers (2)

Marko
Marko

Reputation: 179

I spent one hour with the same problem then I found problem is with the spring development tools. Since the application creates file when batch job complete it causes application restart by spring dev tools. So either remove dev tools from dependencies in case you are using maven or just exclude the path from restart like this:

spring.devtools.restart.exclude=static/**,public/**

Upvotes: 0

Debopam
Debopam

Reputation: 3356

Can you below configuration to applicaion.properties

spring.batch.job.enabled=false
spring.batch.initializer.enabled=false

Upvotes: 0

Related Questions