Spring Batch多个数据源会话/实体管理器已关闭

时间:2018-12-09 15:06:13

标签: spring hibernate spring-data-jpa spring-batch

我正在尝试使用Spring Boot和Sprin Batch(JpaPagingItemReader和JpaItemWriter)将记录从SQLServer数据库中拉出并持久存储到Mysql中。 我已经配置了多个数据源。 我如何面对以下错误。

    org.springframework.batch.item.ItemStreamException: Error while closing item reader
    at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.close(AbstractItemCountingItemStreamItemReader.java:138)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.beans.factory.support.DisposableBeanAdapter.invokeCustomDestroyMethod(DisposableBeanAdapter.java:337)
    at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:271)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:571)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:543)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:957)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:504)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingletons(DefaultListableBeanFactory.java:964)
    at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1041)
    at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1017)
    at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:967)
    at org.springframework.batch.core.launch.support.CommandLineJobRunner.start(CommandLineJobRunner.java:377)
    at org.springframework.batch.core.launch.support.CommandLineJobRunner.main(CommandLineJobRunner.java:597)
    at net.com.org.batch.MyApplication.main(MyApplication.java:15)
Caused by: java.lang.IllegalStateException: Session/EntityManager is closed
    at org.hibernate.internal.AbstractSharedSessionContract.checkOpen(AbstractSharedSessionContract.java:344)
    at org.hibernate.engine.spi.SharedSessionContractImplementor.checkOpen(SharedSessionContractImplementor.java:137)
    at org.hibernate.internal.AbstractSharedSessionContract.checkOpenOrWaitingForAutoClose(AbstractSharedSessionContract.java:350)
    at org.hibernate.internal.SessionImpl.close(SessionImpl.java:413)
    at org.springframework.batch.item.database.JpaPagingItemReader.doClose(JpaPagingItemReader.java:232)
    at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.close(AbstractItemCountingItemStreamItemReader.java:135)
    ... 17 common frames omitted
20:10:55.875 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Retrieved dependent beans for bean 'jpaMappingContext': [mySqljobRepository, sqlServerLogsRepository]

下面是我的批次,步骤配置

   @Autowired
private StepBuilderFactory stepBuilderFactory;

@Autowired
@Qualifier("mysqlEntityManager")
private LocalContainerEntityManagerFactoryBean mysqlLocalContainerEntityManagerFactoryBean;

@Autowired
@Qualifier("secondarySqlEntityManager")
private LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean;

@Autowired
@Qualifier("mysqlTransactionManager")
private PlatformTransactionManager mySqlplatformTransactionManager;


@Autowired
@Qualifier("secondaryTransactionManager")
private PlatformTransactionManager secondaryTransactionManager;


@Autowired
private JobBuilderFactory jobBuilderFactory;

@Bean
public JpaPagingItemReader itemReader(PlatformTransactionManager secondaryTransactionManager) {
    JpaPagingItemReader<SqlServerJobLogs> serverJobLogsJpaPagingItemReader = new JpaPagingItemReader<>();
    serverJobLogsJpaPagingItemReader.setMaxItemCount(1000);
    serverJobLogsJpaPagingItemReader.setPageSize(100);
    serverJobLogsJpaPagingItemReader.setEntityManagerFactory(localContainerEntityManagerFactoryBean.getNativeEntityManagerFactory());
    serverJobLogsJpaPagingItemReader.setQueryString("select p from SqlServerJobLogs p");
    return serverJobLogsJpaPagingItemReader;
}

@Bean
public ItemProcessor itemProcessor() {
    return new DataItemProcessor();
}

@Bean
public ItemWriter itemWriter(PlatformTransactionManager mySqlplatformTransactionManager) {
    DataWriter dataWriter = new DataWriter();
    return dataWriter;
}

@Bean
public Step step() {
    return stepBuilderFactory.get("myJob").chunk(100).reader(itemReader(secondaryTransactionManager)).processor(itemProcessor()).writer(itemWriter(mySqlplatformTransactionManager)).build();
}

@Bean(name = "myJob")
public Job myJob() throws Exception {
    return jobBuilderFactory.get("myJob").start(step()).build();
}

@Bean
public ResourcelessTransactionManager resourcelessTransactionManager(){
    return new ResourcelessTransactionManager();
}

@Bean
public JobRepository jobRepository() throws Exception{
    MapJobRepositoryFactoryBean mapJobRepositoryFactoryBean = new MapJobRepositoryFactoryBean(resourcelessTransactionManager());
    return  mapJobRepositoryFactoryBean.getObject();
}
@Bean
public SimpleJobLauncher jobLauncher() throws Exception {
    SimpleJobLauncher simpleJobLauncher = new SimpleJobLauncher();
    simpleJobLauncher.setJobRepository(jobRepository());
    return simpleJobLauncher;
}

我尝试配置BatchConfigurer,但是不走运。 除了上述详细信息之外,是否还需要配置其他内容,请告诉我

预先感谢

1 个答案:

答案 0 :(得分:0)

我想回答这个问题。 非常感谢@MahmoudBenHassine

  1. 通过覆盖提供自定义交易管理器 DefaultBatchConfigurer#getTransactionManager仅适用于Spring 如评论中所述,批处理v4.1 +。我们需要使用Spring Boot v2.1来 拥有Spring Batch 4.1