无法调用“org.springframework.jdbc.core.JdbcTemplate.update(String, Object[])”,因为“this.jdbcTemplate”为空

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

我有一个 Spring Batch 项目,我需要在 JobExecutionListener 中集成 jdbcTemplate。所以我配置了我的数据源和jdbcTemplate,如下所示:

import java.util.Objects;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.core.JdbcTemplate;

import com.zaxxer.hikari.HikariDataSource;

@Configuration
public class JdbcTemplateConfig {

    @Bean("JdbcBI")
    @Qualifier("JdbcBI")
    public JdbcTemplate jdbcTemplate() {
        final JdbcTemplate template = new JdbcTemplate();
        template.setDataSource(dataSource());
        return template;
    }
    @Bean
    @ConfigurationProperties("spring.datasource.bi")
    public DataSourceProperties biDataSourceProperties() {
        return new DataSourceProperties();
    }
    
    @Bean
    @Qualifier("bi")
    @Primary
    public DataSource dataSource() {
        HikariDataSource ds = new HikariDataSource();
        ds.setJdbcUrl(Objects.requireNonNull(biDataSourceProperties().getUrl()));
        ds.setUsername(Objects.requireNonNull(biDataSourceProperties().getUsername()));
        ds.setPassword(Objects.requireNonNull(biDataSourceProperties().getPassword()));
        ds.setDriverClassName(Objects.requireNonNull(biDataSourceProperties().getDriverClassName()));
        ds.setAutoCommit(true);
        ds.setMaximumPoolSize(20);
        return ds;
    }
}

知道我在 application.properties 文件中声明了我的 dataSource 属性:

spring.datasource.bi.url=jdbc:sqlserver://localhost;databaseName=SQLBI;useBulkCopyForBatchInsert=true;integratedSecurity=false;encrypt=false;trustServerCertificate=false
spring.datasource.bi.username=mongo_user
spring.datasource.bi.password=Azerty
spring.datasource.bi.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.datasource.hikari.data-source-properties.encrypt=false

我正在使用 Spring boot 版本 3.2.2:

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-batch</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>mssql-jdbc</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.batch</groupId>
            <artifactId>spring-batch-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

但是,当我在 JobListener 中使用 jdbcTemplate 时,它会抛出此错误:

java.lang.NullPointerException:无法调用 “org.springframework.jdbc.core.JdbcTemplate.update(字符串,对象[])” 因为“this.jdbcTemplate”为空

这是我的 JobExecutionListener 类:

import org.apache.commons.lang3.StringUtils;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobExecutionListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

@Component
public class CustomJobExecutionListener implements JobExecutionListener {
    
    @Autowired
    JdbcTemplate jdbcTemplate;


    @Override
    public void afterJob(JobExecution jobExecution) {
        String query = "INSERT INTO tabler (Val, Vab, Vai) VALUES ('1', '2', '3')";
        jdbcTemplate.update(query);
    }
}
spring-boot spring-batch jdbctemplate
2个回答
0
投票

我需要做的就是在“CustomJobExecutionListener”中正确定义我的jdbcTemplate:

private final JdbcTemplate jdbcTemplate;

    public CustomJobExecutionListener(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

0
投票

您已声明:

@Bean("JdbcBI")
@Qualifier("JdbcBI")
public JdbcTemplate jdbcTemplate() {
    final JdbcTemplate template = new JdbcTemplate();
    template.setDataSource(dataSource());
    return template;
}

当你将 bean 注入另一个服务时,你必须使用

@Qulifier
:

@Autowired
@Qualifier("JdbcBI")
private JdbcTemplate jdbcTemplate;
© www.soinside.com 2019 - 2024. All rights reserved.