Spring Batch ResourcelessTransactionManager与persistence.xml混淆了吗?

时间:2018-08-07 10:13:05

标签: spring spring-batch

我正在处理一个应用程序,已被要求实施计划的春季批处理作业。我已经设置了一个配置文件,在其中设置了onTouch @Bean,但似乎与ResourcelessTransactionManager混为一谈。

另一个模块中已经存在一个持久性xml,没有编译错误。当我请求返回一个视图项的页面时,我得到了persistence.xml

这是错误:

NoUniqueBeanDefinitionException

是否有一种方法可以告诉Spring Batch使用另一个模块的persistence.xml中定义的数据源,或者这是由其他原因引起的?

2 个答案:

答案 0 :(得分:1)

我如下创建了单独的BatchScheduler Java类,并将其包含在BatchConfiguration Java类中。我要同时分享这两个课程。 BatchConfiguration包含另一个jpaTransactionManager。

    import org.springframework.batch.core.repository.JobRepository;
    import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
    import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.annotation.EnableScheduling;

    @Configuration
    @EnableScheduling
    public class BatchScheduler {

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

@Bean
public MapJobRepositoryFactoryBean mapJobRepositoryFactory(
        ResourcelessTransactionManager resourcelessTransactionManager) throws Exception {

    MapJobRepositoryFactoryBean factory = new 
            MapJobRepositoryFactoryBean(resourcelessTransactionManager);

    factory.afterPropertiesSet();

    return factory;
}

@Bean
public JobRepository jobRepository(
        MapJobRepositoryFactoryBean factory) throws Exception {
    return factory.getObject();
}

@Bean
public SimpleJobLauncher jobLauncher(JobRepository jobRepository) {
    SimpleJobLauncher launcher = new SimpleJobLauncher();
    launcher.setJobRepository(jobRepository);
    return launcher;
}

    }

BatchConfiguration包含另一个jpaTransactionManager。

    import java.io.IOException;
    import java.util.Date;
    import java.util.Properties;

    import javax.sql.DataSource;

    import org.springframework.batch.core.Job;
    import org.springframework.batch.core.JobExecution;
    import org.springframework.batch.core.JobParameters;
    import org.springframework.batch.core.JobParametersBuilder;
    import org.springframework.batch.core.Step;
    import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
    import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
    import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
    import org.springframework.batch.core.configuration.annotation.StepScope;
    import org.springframework.batch.core.launch.JobLauncher;
    import org.springframework.batch.core.launch.support.RunIdIncrementer;
    import org.springframework.batch.item.database.JpaItemWriter;
    import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper;
    import org.springframework.batch.item.file.mapping.DefaultLineMapper;
    import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Import;
    import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
    import org.springframework.core.env.Environment;
    import org.springframework.core.io.FileSystemResource;
    import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
    import org.springframework.jdbc.datasource.DriverManagerDataSource;
    import org.springframework.orm.jpa.JpaTransactionManager;
    import org.springframework.orm.jpa.JpaVendorAdapter;
    import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
    import org.springframework.orm.jpa.vendor.Database;
    import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
    import org.springframework.scheduling.TaskScheduler;
    import org.springframework.scheduling.annotation.EnableScheduling;
    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler;
    import org.springframework.transaction.PlatformTransactionManager;

    import trade.api.common.constants.Constants;
    import trade.api.entity.SecurityEntity;
    import trade.api.trade.batch.item.processor.SecurityItemProcessor;
    import trade.api.trade.batch.item.reader.NseSecurityReader;
    import trade.api.trade.batch.notification.listener.SecurityJobCompletionNotificationListener;
    import trade.api.trade.batch.tasklet.SecurityReaderTasklet;
    import trade.api.vo.SecurityVO;

    @Configuration
    @EnableBatchProcessing
    @EnableScheduling
    @Import({OhlcMonthBatchConfiguration.class, OhlcWeekBatchConfiguration.class, OhlcDayBatchConfiguration.class, OhlcMinuteBatchConfiguration.class})
    public class BatchConfiguration {

        private static final String OVERRIDDEN_BY_EXPRESSION = null;

        /*
           Load the properties
        */
        @Value("${database.driver}")
        private String databaseDriver;
        @Value("${database.url}")
        private String databaseUrl;
        @Value("${database.username}")
        private String databaseUsername;
        @Value("${database.password}")
        private String databasePassword;

        @Autowired
        public JobBuilderFactory jobBuilderFactory;

        @Autowired
        public StepBuilderFactory stepBuilderFactory;

        @Autowired
        private JobLauncher jobLauncher;

        @Bean
        public TaskScheduler taskScheduler() {
            return new ConcurrentTaskScheduler();
        }

        //second, minute, hour, day of month, month, day(s) of week
        //@Scheduled(cron = "0 0 21 * * 1-5") on week days
        @Scheduled(cron="${schedule.insert.security}")
        public void importSecuritySchedule() throws Exception {

            System.out.println("Job Started at :" + new Date());

            JobParameters param = new JobParametersBuilder().addString("JobID",
                    String.valueOf(System.currentTimeMillis())).toJobParameters();

            JobExecution execution = jobLauncher.run(importSecuritesJob(), param);

            System.out.println("Job finished with status :" + execution.getStatus());
        }

        @Bean SecurityJobCompletionNotificationListener securityJobCompletionNotificationListener() {
            return new SecurityJobCompletionNotificationListener();
        }




        //Import Equity OHLC End

        //Import Equity Start
        // tag::readerwriterprocessor[]

        @Bean
        public SecurityReaderTasklet securityReaderTasklet() {
            return new SecurityReaderTasklet();
        }

        @Bean
        @StepScope
        public NseSecurityReader<SecurityVO> nseSecurityReader(@Value("#{jobExecutionContext["+Constants.SECURITY_DOWNLOAD_FILE+"]}") String pathToFile) throws IOException {

            NseSecurityReader<SecurityVO> reader = new NseSecurityReader<SecurityVO>();
            reader.setLinesToSkip(1);
            reader.setResource(new FileSystemResource(pathToFile));
            reader.setLineMapper(new DefaultLineMapper<SecurityVO>() {{
                setLineTokenizer(new DelimitedLineTokenizer() {{
                    setNames(new String[] { "symbol", "nameOfCompany", "series", "dateOfListing", "paidUpValue", "marketLot", "isinNumber", "faceValue" });
                }});
                setFieldSetMapper(new BeanWrapperFieldSetMapper<SecurityVO>() {{
                    setTargetType(SecurityVO.class);
                }});
            }});
            return reader;
        }


        @Bean
        public SecurityItemProcessor processor() {
            return new SecurityItemProcessor();
        }

        @Bean
        public JpaItemWriter<SecurityEntity> writer() {
            JpaItemWriter<SecurityEntity> writer = new JpaItemWriter<SecurityEntity>();
            writer.setEntityManagerFactory(entityManagerFactory().getObject());
            return writer;
        }
        // end::readerwriterprocessor[]

        // tag::jobstep[]
        @Bean
        public Job importSecuritesJob() throws IOException {
            return jobBuilderFactory.get("importSecuritesJob")
                    .incrementer(new RunIdIncrementer())
                    .listener(securityJobCompletionNotificationListener())
                    .start(downloadSecurityStep())
                    .next(insertSecurityStep())
                    .build();
        }

        @Bean
        public Step downloadSecurityStep() throws IOException {
            return stepBuilderFactory.get("downloadSecurityStep")
                    .tasklet(securityReaderTasklet())
                    .build();
        }

        @Bean
        public Step insertSecurityStep() throws IOException {
            return stepBuilderFactory.get("insertSecurityStep")
                    .transactionManager(jpaTransactionManager())
                    .<SecurityVO, SecurityEntity> chunk(100)
                    .reader(nseSecurityReader(OVERRIDDEN_BY_EXPRESSION))
                    .processor(processor())
                    .writer(writer())
                    .build();
        }
        // end::jobstep[]

        //Import Equity End

        @Bean
        public DataSource dataSource() {
            DriverManagerDataSource dataSource = new DriverManagerDataSource();
            dataSource.setDriverClassName(databaseDriver);
            dataSource.setUrl(databaseUrl);
            dataSource.setUsername(databaseUsername);
            dataSource.setPassword(databasePassword);
            return dataSource;
        }


        @Bean
        public LocalContainerEntityManagerFactoryBean entityManagerFactory() {

            LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
            lef.setPackagesToScan("trade.api.entity");
            lef.setDataSource(dataSource());
            lef.setJpaVendorAdapter(jpaVendorAdapter());
            lef.setJpaProperties(new Properties());
            return lef;
        }


        @Bean
        public JpaVendorAdapter jpaVendorAdapter() {
            HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
            jpaVendorAdapter.setDatabase(Database.MYSQL);
            jpaVendorAdapter.setGenerateDdl(true);
            jpaVendorAdapter.setShowSql(false);
            jpaVendorAdapter.setDatabasePlatform("org.hibernate.dialect.MySQLDialect");
            return jpaVendorAdapter;
        }

        @Bean
        @Qualifier("jpaTransactionManager")
        public PlatformTransactionManager jpaTransactionManager() {
               return new JpaTransactionManager(entityManagerFactory().getObject());
        }

        @Bean
        public static PropertySourcesPlaceholderConfigurer dataProperties(Environment environment) throws IOException {
            String[] activeProfiles = environment.getActiveProfiles();
            final PropertySourcesPlaceholderConfigurer ppc = new PropertySourcesPlaceholderConfigurer();
            ppc.setLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:application-"+activeProfiles[0]+".properties"));
            return ppc;
        }
        //// Import Security End
    }

答案 1 :(得分:0)

问题解决了。在另一个配置文件中有一个PlatformTransactionManager bean。我将其设置为@Primary,现在问题已解决。谢谢大家的帮助。