Reputation: 402
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";
}
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
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
Reputation: 3356
Can you below configuration to applicaion.properties
spring.batch.job.enabled=false
spring.batch.initializer.enabled=false
Upvotes: 0