gpt4 book ai didi

hibernate - Spring Batch - 模块化批处理范围规则

转载 作者:行者123 更新时间:2023-12-02 01:46:35 26 4
gpt4 key购买 nike

我有一个玩具项目,该项目将人名和怪物的名称列表导入数据库,然后使用 then 将怪物的姓氏更改为 Monster。要将项目写入数据库,我正在使用 HibernateItemWriter

这 3 个作业中的每一个都有自己的配置文件,它们被捆绑在一个带有 @EnableBatchProcessing(modular=true) 注释的配置中。

一切正常。

但是,当@EnableBatchProcessing 出现在各个作业的配置文件中时,HibernateItemWriter 无法再找到 hibernate session 。

有人可以解释实现这一点的应用程序上下文范围规则吗?

当不单独使用它们时,在单独的 Job 配置上使用 @EnableBatchProcessing 是相当不错的。它允许在 spring 自动配置完成工作时导入和运行它们。

应用

@Import({ImportAllConfiguration.class, EmbededDatasourceConfiguration.class, HibernateConfiguration.class})
@Configuration
public class Application {


public static void main(String[] args) throws SQLException, BeansException, JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException, NoSuchJobException, JobParametersInvalidException {
ApplicationContext ctx = SpringApplication.run(Application.class, args);

JobRegistry jobRegistry = ctx.getBean(JobRegistry.class);
Job job1 = jobRegistry.getJob("importMonsterJob");

JobLauncher launcher = ctx.getBean(JobLauncher.class);
launcher.run(job1, new JobParameters());

}

}

ImportAllConfiguration

@Configuration
@EnableBatchProcessing(modular=true)
public class ImportAllConfiguration {
@Bean
public ApplicationContextFactory someJobs() {
return new GenericApplicationContextFactory(ImportMonsterConfiguration.class);
}

@Bean
public ApplicationContextFactory someMoreJobs() {
return new GenericApplicationContextFactory(ImportPersonConfiguration.class);
}

@Bean
public ApplicationContextFactory evenMoreJobs() {
return new GenericApplicationContextFactory(MatchMonsterToPersonConfiguration.class);
}
}

hibernate 配置

@Configuration
public class HibernateConfiguration {

@Autowired
private DataSource dataSource;

@Bean
public HibernateTransactionManager transactionManager(
SessionFactory sessionFactory) {
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(sessionFactory);

return txManager;
}

@Bean
public JdbcTemplate jdbcTemplate() {
JdbcTemplate jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(dataSource);
return jdbcTemplate;
}

@SuppressWarnings("serial")
public Properties hibernateProperties() {
return new Properties() {
{
//setProperty(Environment.CURRENT_SESSION_CONTEXT_CLASS, "thread");
setProperty(Environment.HBM2DDL_AUTO, "create");
setProperty(Environment.SHOW_SQL, "true");
}
};
}

@Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean annotationSessionFactoryBean = new LocalSessionFactoryBean();
annotationSessionFactoryBean.setPackagesToScan("hello.model");

annotationSessionFactoryBean.setDataSource(dataSource);
annotationSessionFactoryBean
.setHibernateProperties(hibernateProperties());
return annotationSessionFactoryBean;
}

}

作业配置文件。在此处添加@EnableBatchProcessing 将导致HibernateItemWriter 无法找到 session 。

@Configuration
@EnableBatchProcessing <-- This causes the exception
public class ImportMonsterConfiguration {

@Autowired
protected SessionFactory sessionFactory;

@Autowired
protected StepBuilderFactory stepBuilderFactory;

@Autowired
protected JobBuilderFactory jobBuilderFactory;

@Bean
public <T> ItemWriter<T> writer() {
return new HibernateItemWriter<T>() {
{
setSessionFactory(sessionFactory);
}
};
}

@Bean
public ItemReader<Monster> reader() {
FlatFileItemReader<Monster> reader = new FlatFileItemReader<Monster>();
reader.setResource(new ClassPathResource("sample-data.csv"));
reader.setLineMapper(new DefaultLineMapper<Monster>() {
{
setLineTokenizer(new DelimitedLineTokenizer() {
{
setNames(new String[] { "firstName", "lastName" });
}
});
setFieldSetMapper(new BeanWrapperFieldSetMapper<Monster>() {
{
setTargetType(Monster.class);
}
});
}
});
return reader;
}

@Bean
public ItemProcessor<Monster, Monster> processor() {
return new MonsterItemProcessor();
}

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

@Bean
public LocalValidatorFactoryBean validator() {
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
return validator;
}

@Bean
public ItemProcessor<Monster, Monster> validatingProcessor() {
SpringValidator<Monster> springValidator = new SpringValidator<Monster>();
springValidator.setValidator(validator());

ValidatingItemProcessor<Monster> validatingItemProcessor = new ValidatingItemProcessor<Monster>();
validatingItemProcessor.setValidator(springValidator);

return validatingItemProcessor;
}

@Bean
public Step step2() {
return stepBuilderFactory.get("step2").<Monster, Monster> chunk(10)
.reader(reader()).processor(processor())
.processor(validatingProcessor()).writer(writer()).build();
}

}

抛出的异常。

org.hibernate.HibernateException: No Session found for current thread
at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:106)
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1014)
at org.springframework.batch.item.database.HibernateItemWriter.doWrite(HibernateItemWriter.java:134)
at org.springframework.batch.item.database.HibernateItemWriter.write(HibernateItemWriter.java:113)

最佳答案

您正在提供自己的事务管理器。要覆盖 Spring Batch 使用 @EnableBatchProcessing 提供的那些,您需要提供自己的 BatchConfigurer 实现。否则,我们将为您添加一个,在这种情况下,它不会是基于 Hibernate 的事务管理器。让 HibernateConfiguration 扩展 DefaultBatchConfigurer 并用您的事务管理器代码覆盖 getTransactionManager 方法。

关于hibernate - Spring Batch - 模块化批处理范围规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25332568/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com