You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中JdbcTemplate为空触发NullPointerException问题求助

jdbcTemplate为空并抛出NullPointerException

您好,能否有人解释为何我的JDBC DAO方法无法运行并抛出该异常?我尝试修改了SQL语句并进行了调试,参数已经传递到方法中,但jdbcTemplate仍为空,请求帮忙排查原因。


控制器代码

@Controller
public class MainPageController {
    private final VehicleDAO vehicleDAO;
    private final UserDAO userDAO;

    @Autowired
    public MainPageController(VehicleDAO vehicleDAO, UserDAO userDAO) {
        this.vehicleDAO = vehicleDAO;
        this.userDAO = userDAO;
    }
    @GetMapping("/main")
    public String index(UserDAO user, Model model) {
        model.addAttribute("vehicles", vehicleDAO.index());
        model.addAttribute("user", userDAO.currentUser());
        return "main";
    }

    @GetMapping("/new-vehicle")
    public String newCar(@ModelAttribute("vehicle") Vehicle vehicle) {
        return "new-vehicle";
    }

    @PostMapping("/new-vehicle")
    public String addCar(@ModelAttribute("vehicle") Vehicle vehicle,
                         VehicleDAO vehicleDAO) {
        vehicleDAO.add(vehicle);
        return "redirect:/main";
    }
}

VehicleDAO代码

@Component
public class VehicleDAO {
    private final JdbcTemplate jdbcTemplate;

    @Autowired
    public VehicleDAO(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public List<Vehicle> index() {
        return jdbcTemplate.query("SELECT * FROM vehicles", new BeanPropertyRowMapper<>(Vehicle.class));
    }

    public void add(Vehicle vehicle) {
        jdbcTemplate.update("INSERT INTO vehicles (car_brand, car_year, price_rent) VALUES(?, ?, ?)", vehicle.getCAR_BRAND(),
                vehicle.getCAR_YEAR(), vehicle.getPRICE_RENT()); // 此处出现问题
    }
}

Vehicle实体类

public class Vehicle {
    private int CAR_ID;
    private String CAR_BRAND;
    private int PRICE_RENT;
    private int CAR_YEAR;

    public Vehicle() {
    }

    public String getCAR_BRAND() {
        return CAR_BRAND;
    }

    public void setCAR_BRAND(String CAR_BRAND) {
        this.CAR_BRAND = CAR_BRAND;
    }

    public int getPRICE_RENT() {
        return PRICE_RENT;
    }

    public void setPRICE_RENT(int PRICE_RENT) {
        this.PRICE_RENT = PRICE_RENT;
    }

    public int getCAR_YEAR() {
        return CAR_YEAR;
    }

    public void setCAR_YEAR(int CAR_YEAR) {
        this.CAR_YEAR = CAR_YEAR;
    }

    public int getCAR_ID() {
        return CAR_ID;
    }

    public void setCAR_ID(int CAR_ID) {
        this.CAR_ID = CAR_ID;
    }

    public Vehicle(String CAR_BRAND, int PRICE_RENT, int CAR_YEAR, int CAR_ID) {
        this.CAR_BRAND = CAR_BRAND;
        this.PRICE_RENT = PRICE_RENT;
        this.CAR_YEAR = CAR_YEAR;
        this.CAR_ID = CAR_ID;
    }
}

POM.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.0.6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>pl.messages</groupId>
    <artifactId>web</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>web</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</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.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.hibernate.validator</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>8.0.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.jetbrains</groupId>
            <artifactId>annotations</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

配置文件

spring.datasource.url=jdbc:postgresql://localhost:5432/CoolStoreDB
spring.datasource.username=user
spring.datasource.password=user

控制台报错信息

2023-05-14T18:51:03.496+02:00  INFO 9688 --- [  restartedMain] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729
2023-05-14T18:51:03.549+02:00  INFO 9688 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2023-05-14T18:51:03.563+02:00  INFO 9688 --- [  restartedMain] pl.messages.web.WebApplication           : Started WebApplication in 4.326 seconds (process running for 5.201)
2023-05-14T18:51:18.616+02:00  INFO 9688 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2023-05-14T18:51:18.616+02:00  INFO 9688 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2023-05-14T18:51:18.618+02:00  INFO 9688 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 2 ms
2023-05-14T18:51:18.707+02:00 ERROR 9688 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.NullPointerException: Cannot invoke "org.springframework.jdbc.core.JdbcTemplate.update(String, Object[])" because "this.jdbcTemplate" is null] with root cause

java.lang.NullPointerException: Cannot invoke "org.springframework.jdbc.core.JdbcTemplate.update(String, Object[])" because "this.jdbcTemplate" is null
    at pl.messages.web.dao.VehicleDAO.add(VehicleDAO.java:22) ~[classes/:na]
    at pl.messages.web.controller.MainPageController.addCar(MainPageController.java:41) ~[classes/:na]

问题原因及解决方法

核心问题

你在MainPageController的addCar方法里,额外声明了一个方法参数VehicleDAO vehicleDAO,这个参数会被Spring当作请求参数处理,而非注入容器中已初始化的Bean。由于请求未传递该参数,Spring会创建一个未初始化的VehicleDAO实例(未调用带JdbcTemplate的构造方法),导致jdbcTemplate为null。

而控制器类已经通过构造注入了全局的vehicleDAO,完全不需要在方法里重复声明。

修复步骤

修改addCar方法,移除方法参数中的VehicleDAO vehicleDAO,直接使用类中已注入的全局实例:

@PostMapping("/new-vehicle")
public String addCar(@ModelAttribute("vehicle") Vehicle vehicle) {
    vehicleDAO.add(vehicle); // 使用类成员变量的vehicleDAO
    return "redirect:/main";
}

额外优化建议

  • POM中同时引入了spring-boot-starter-data-jdbc、spring-boot-starter-data-jpa、spring-boot-starter-data-mongodb、spring-boot-starter-data-redis,若未用到全部持久化技术,建议移除不必要的依赖,避免冗余初始化和潜在冲突。
  • 实体类字段全大写不符合Java命名规范,建议改为小驼峰(如carId、carBrand),配合@Column注解映射数据库字段,提升代码可读性。

内容的提问来源于stack exchange,提问作者murakami w slancah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 03:32:36