在spring批处理作业中,我有一个步骤,我想使用Hibernate从数据库中按块读取数据,进行处理并将其写回到数据库中。现在我在设置阅读器时遇到了一些麻烦:
@EnableBatchProcessing
@Configuration
@ComponentScan(basePackages = {"com.x.y.z.database", "com.x.y.p.database"}, excludeFilters={
@ComponentScan.Filter(type= FilterType.ASSIGNABLE_TYPE, value=ConfigHelperMail.class)})
@EntityScan(basePackages = {"com.x.y.z.database", "com.x.y.p.database"})
@EnableJpaRepositories({"com.x.y.z.database", "com.x.y.p.database"})
public class BatchConfiguration {
@Autowired
public JobBuilderFactory jobs;
@Bean
public Job job(CustomJobListener listener,
@Qualifier("step1") Step step1,
@Qualifier("step2") Step step2,
@Qualifier("step3") Step step3) {
return jobs.get("SimpleJobName")
.incrementer(new RunIdIncrementer())
.preventRestart()
.listener(listener)
.start(step1)
.next(step2)
.next(step3)
.build();
}
}
在step1
编写器中,我使用Hibernate将数据保存到数据库中:
@Entity
@Table(name = "tmp_z_stepone")
public class StepOneEntity {
@Id
@Column(name = "reference")
private String reference;
/** Other properties and getters and setters **/
}
@Component
public class StepOneWriter implements ItemWriter<StepOneEntity> {
@Autowired
private StepOneService stepOneService;
@Override
public void write (List<? extends StepOneEntity> items) throws WriterException {
stepOneService.saveMany(items);
}
}
StepOneService
带有@Service
注释,它使用扩展了CrudRepository<StepOneEntity, String>
的DAO接口,其saveMany
方法仅使用{{1 }}。
第2步
save
我认为我正在对一些会话/ ORM配置进行任务,但是我不知道在哪里,错误如下:
CrudRepository<StepOneEntity, String>
答案 0 :(得分:1)
HibernateCursorItemReader
实现了InitializingBean
接口,这意味着如果将Spring声明为bean,它将在容器初始化时调用其afterPropertiesSet
。但是,在您的情况下,HibernateCursorItemReader
在应用程序上下文中未声明为Bean,而是包装在一个类(StepTwoReader
)中,然后使用reader.read()
创建。
如果使用HibernateCursorItemReader
方法中的当前代码将read
声明为bean,则应该获得一个IllegalStateException
并显示消息:“必须提供SessionFactory”。实际上,您实际上需要为Hibernate阅读器配置SessionFactory
。
另一种选择是使用HibernateCursorItemReaderBuilder
,以确保正确配置阅读器。
答案 1 :(得分:1)
@StepScope
@Slf4j
@Component
public class CursorItemReader extends HibernateCursorItemReader<ItemEntity> {
public CursorItemReader(EntityManagerFactory entityManagerFactory,
@Value("#{stepExecution}")StepExecution stepExecution) {
this.setName("CursorItemReader");
this.setSessionFactory(entityManagerFactory.createEntityManager().unwrap(org.hibernate.Session.class).getSessionFactory());
this.setQueryString("from ItemEntity");
this.setUseStatelessSession(true);
this.setFetchSize(5);
}
@Override
public ItemEntity read() throws Exception {
ItemEntity item = this.doRead();
return item;
}
}