JdBcPagingItemReader 因步骤配置的 NamedJdbcParameter 为空而失败

问题描述 投票:0回答:1

我正在尝试为批处理创建一个简单的步骤,该步骤从项目处理器获取 ProductDetail 信息和其他信息来创建新的 ProductResult 并将其写入 Mongodb 数据库。我正在尝试使用 JdbcPagingItemReader 从数据库读取数据。但是,当我开始工作时,它失败并出现错误

java.lang.NullPointerException: Cannot invoke "org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.getJdbcOperations()" because "this.namedParameterJdbcTemplate" is null. 

我还用另一个阅读器测试了它,它可以工作,所以这只是 JdbcPagingItemReader 的问题。

我不知道为什么需要 NamedParameterJdbcTemplate,因为我已经提供了 select 和 from 值以及配置的行映射器。

这是我的代码


    import com.datacom.mapper.ProductDetailRowMapper;
    import com.datacom.model.ProductDetail;
    import lombok.RequiredArgsConstructor;
    import org.springframework.batch.core.Step;
    import org.springframework.batch.core.repository.JobRepository;
    import org.springframework.batch.core.step.builder.StepBuilder;
    import org.springframework.batch.item.ItemStreamReader;
    import org.springframework.batch.item.ItemWriter;
    import org.springframework.batch.item.data.MongoItemWriter;
    import org.springframework.batch.item.data.builder.MongoItemWriterBuilder;
    import org.springframework.batch.item.database.JdbcPagingItemReader;
    import org.springframework.batch.item.database.Order;
    import org.springframework.batch.item.database.support.OraclePagingQueryProvider;
    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.data.mongodb.core.MongoOperations;
    import org.springframework.transaction.PlatformTransactionManager;
    
    import javax.sql.DataSource;
    import java.util.HashMap;
    import java.util.Map;
    
    @Configuration
    @RequiredArgsConstructor
    public class ProductDetailConfigStep {
    
        @Value("${db.pageSize}")
        int pageSize;
    
        final MongoOperations mongoOperations;
    
        final @Qualifier("productsDataSource") DataSource dataSource;
    
        final PlatformTransactionManager transactionManager;
    
    
        final JobRepository jobRepository;
    
        @Value("${batch.chunkSize}") int chunkSize;
    
        final ProductResultProcessor productResultProcessor;
    
        public ItemStreamReader<ProductDetail> itemReader() {
            JdbcPagingItemReader<ProductDetail> itemReader = new JdbcPagingItemReader<>();
            itemReader.setDataSource(productsDataSource);
            itemReader.setFetchSize(chunkSize);
            OraclePagingQueryProvider queryProvider = new OraclePagingQueryProvider();
            queryProvider.setSelectClause(JDBCConstants.SELECT_QUERY);
            queryProvider.setFromClause(JDBCConstants.FROM_CLAUSE_QUERY);
            itemReader.setRowMapper(new ProductDetailRowMapper());
            final Map<String, Order> sortKeys = new HashMap<>();
            itemReader.setParameterValues(new HashMap<>());
            sortKeys.put("product_id", Order.ASCENDING);
            queryProvider.setSortKeys(sortKeys);
            itemReader.setQueryProvider(queryProvider);
            itemReader.setPageSize(pageSize);
            itemReader.setPageSize(chunkSize);
            return itemReader;
        }
    
        public ItemWriter<ProductResult> itemWriter() {
            var writer = new MongoItemWriterBuilder<ProductResult>()
                    .collection(Documents.PRODUCT_CATALOG_COLLECTION)
                    .mode(MongoItemWriter.Mode.INSERT)
                    .template(mongoOperations)
                    .build();
            writer.setTemplate(mongoOperations);
            return writer;
        }
    
        @Bean("productProcessingDetailStep")
        public Step productProcessingDetailStep() {
            return new StepBuilder("productCreationStep", jobRepository)
                    .<ProductDetail, ProductResult>chunk(chunkSize, transactionManager)
                    .reader(itemReader())
                    .processor(productResultProcessor)
                    .writer(itemWriter())
                    .build();
        }
    }

我缺少什么 JdbcPagingItemReader 的配置对我来说看起来很好。

spring-data spring-batch spring-jdbc
1个回答
0
投票

字段

namedParameterJdbcTemplate
null
,因为读者的方法
afterProperties
没有被调用。

如果你将 reader 作为 bean 公开,那么 Spring 会为你调用这个方法。但如果读者没有其他需要的话,你也可以自己做。

如果您像这样更改代码,它应该按预期工作:

public ItemStreamReader<ProductDetail> itemReader() throws Exception {
    ...
    itemReader.afterPropertiesSet();
    return itemReader;
}

请注意方法签名中的

throws Exception
。或者,您可以将对
afterPropertiesSet
的调用包装在适当的 try-catch 块中。

© www.soinside.com 2019 - 2024. All rights reserved.