我正在将Spring Boot项目与Spring批处理和数据jpa项目集成。所有与作业和数据配置相关的东西都是正确的,除了将我的作业编写器结果保存在数据库中。在我读取文件并对其进行处理后,我无法将其写入mysql数据库。没有错误,但也没有插入。有趣的是我的数据源已配置。因为在插入之前,我可以从数据库中获取示例记录。请协助我解决这个问题。
我的申请。属性:
spring.datasource.url = jdbc:mysql://localhost:3306/batchtest? characterEncoding=UTF-8&autoReconnect=true
spring.datasource.username = root
spring.datasource.password = root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
批次配置:
@Configuration
@EnableBatchProcessing
public class BatchConfiguration {
@Autowired
public JobBuilderFactory jobBuilderFactory;
@Autowired
public StepBuilderFactory stepBuilderFactory;
@Bean
public ResourcelessTransactionManager transactionManager() {
return new ResourcelessTransactionManager();
}
@Bean
public JobRepository jobRepository(ResourcelessTransactionManager transactionManager) throws Exception {
MapJobRepositoryFactoryBean mapJobRepositoryFactoryBean = new MapJobRepositoryFactoryBean(transactionManager);
mapJobRepositoryFactoryBean.setTransactionManager(transactionManager);
return mapJobRepositoryFactoryBean.getObject();
}
@Bean
public SimpleJobLauncher jobLauncher(JobRepository jobRepository) {
SimpleJobLauncher simpleJobLauncher = new SimpleJobLauncher();
simpleJobLauncher.setJobRepository(jobRepository);
return simpleJobLauncher;
}
@Bean
public FlatFileItemReader<Person> reader() {
FlatFileItemReader<Person> reader = new FlatFileItemReader<Person>();
reader.setResource(new ClassPathResource("sample-data.csv"));
reader.setLineMapper(new DefaultLineMapper<Person>() {{
setLineTokenizer(new DelimitedLineTokenizer() {{
setNames(new String[] { "firstName", "lastName" });
}});
setFieldSetMapper(new BeanWrapperFieldSetMapper<Person>() {{
setTargetType(Person.class);
}});
}});
return reader;
}
@Bean
public PersonItemProcessor processor() {
return new PersonItemProcessor();
}
@Bean
public ItemWriter<Person> writer() throws Exception {
return new PersonWriter();
}
@Bean
public Job importUserJob() throws Exception{
return jobBuilderFactory.get("importUserJob")
.incrementer(new RunIdIncrementer())
.flow(step1())
.end()
.build();
}
@Bean
public Step step1() throws Exception{
return stepBuilderFactory.get("step1")
.<Person, Person> chunk(1)
.reader(reader())
.processor(processor())
.writer(writer())
.build();
}
道类:
public interface PersonDao extends CrudRepository<Person,Integer> {
}
作家类:
public class PersonWriter implements ItemWriter<Person> {
@Autowired
PersonDao personDao;
@Override
public void write(List<? extends Person> items) throws Exception {
LOGGER.info("Received the information of {} students", items.size());
for(Person person:items)
{
LOGGER.info(String.format("inserting for customre %s %s", person.getFirstName(), person.getLastName()));
Person tempPerson = personDao.findOne(1);
personDao.save(person) ;
LOGGER.info(String.format("person id : %d",person.getId()));
}
}
temPerson是一个用于测试jpa数据的对象。它从数据库中获取一个id为1的人对象,但下一行没有插入数据库而没有错误。只是执行该行并继续循环。
我可能错过了它,但我看不到您在哪里指定您正在使用的DB访问方法(JPA、Hibernate、JDBC等)。我假设是JPA,但我认为您的ItemWriter需要扩展一个DB感知的ItemWriter(RepositoryItemWriter、JpaItemWriter、JdbcBatchItemWriter、HibernateItemWriter)。基本ItemWriter希望您自己管理事务和所有资源。尝试改用RepositoryItemWriter(或任何合适的)。您可能必须提供EntityManager,并确保从事务中调用write(例如,一些事务性方法)。
这个问题的解决方案可能比预期的更接近。您是否只是尝试更改transactionManager bean的名称?如果使用不同的名称,Spring数据JPA默认情况下不会使用它。
我重现了你的问题,然后我简单地从以下方面切换:
@Bean
public ResourcelessTransactionManager transactionManager() {
return new ResourcelessTransactionManager();
}
对此:
@Bean
public ResourcelessTransactionManager resourcelessTransactionManager() {
return new ResourcelessTransactionManager();
}
在我看来,这解决了问题。请记住,“transactionManager”是Spring Data JPA中transactionManager的默认bean名称(至少据我所知,Spring Boot会自动配置它,除非它找到一个具有该名称的bean,如果找到了,它会使用找到的bean,而您的数据库事务将通过一个无资源的bean)。
您也可以跳过此操作:
@Bean
public JobRepository jobRepository(ResourcelessTransactionManager transactionManager) throws Exception {
return new MapJobRepositoryFactoryBean(transactionManager).getObject();
}
并直接调用bean(只是为了“更确定”在批处理中使用了适当的事务管理器):
@Bean
public JobRepository jobRepository() throws Exception {
return new MapJobRepositoryFactoryBean(resourcelessTransactionManager()).getObject();
}
让我知道当你测试它,我希望这是主要问题:)
我正在尝试将BeanIO与spring Batch集成。使用BeanIO,我正在读取一个固定长度的流文件。我已经测试并验证了使用独立类读取平面文件的代码,它可以无缝地工作,但是当我试图将它与Spring Batch集成时,BeanIOFlatFileItemReader的doRead()方法没有被调用,而且我编写的RedemptionEventCustomProcessor是如何直接被调用的。 我
我有一个spring批处理应用程序,它从文件中读取数据,进行一些处理,最后编写一个定制的输出。这一切都是一步到位的。在下一步中,我将使用一个tasklet来归档输入文件(移动到另一个文件夹)。这个应用程序运行良好。但是,现在我需要在远程服务器上对sftp输出文件进行进一步处理。我找到了一种使用spring integration实现sftp的方法,在这里我创建了一个输入通道,该通道将反馈给outb
我希望能够使用在作业配置中定义的以相同的参数(基本上是相同的文件)重新启动作业(可能是因为应用程序已经重新启动,或者由于某些原因我们再次收到了相同的文件)。 不幸的是,run.id=1没有增加,我得到一个 作业配置 多谢
批处理配置具有spring作业,只有一个步骤 1)读取器-从csv文件读取。处理器对文件应用一些规则。Drools请运行schema-postgresql.sql来设置数据库 WRITER使用SPRING DATA JPA写入DB Writer将此称为PersonDaoImpl:
我是Spring的新人。最近我试着让Spring批处理和Spring集成一起工作。我想有一个JobListener,它会监听消息到达特定的频道并启动Spring批处理作业。 我在github上找到了一个例子(https://github.com/chrisjs/spring-batch-scaling/tree/master/message-job-launch)我试图以某种方式将Spring批处
在happy path场景中,我有一个spring批处理工作,但现在我将重点放在错误处理上。 但是,在另一个测试中,我想证明一个不可预见的数据库错误会导致作业失败。为此,我创建了一个触发器,该触发器会导致对要插入的表的插入失败。 这似乎起作用了,在writer执行之后,在事务提交期间抛出异常,并且我得到以下日志消息: 这似乎也是预期的行为。问题是,这并不能阻止工作。该步骤退出到SimplyRetr