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

Docker Compose部署Spring Boot+MySQL应用遇空指针错误求助

问题描述

尝试在线部署Spring Boot+MySQL应用,已编写Dockerfile和docker-compose.yml,docker-compose build执行成功,但docker-compose up时出现如下空指针错误(本地运行无问题)。AWS账户存在问题暂无法使用,计划容器化完成后部署至Render或Railway平台。

报错信息:

springboot-app-1 | java.lang.NullPointerException: Cannot invoke "org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(java.sql.SQLException, String)" because the return value of "org.hibernate.resource.transaction.backend.jdbc.internal.JdbcIsolationDelegate.sqlExceptionHelper()" is null

相关配置文件

Dockerfile

# base image containing Java runtime
FROM openjdk:17-jdk-alpine

# volume pointing to /tmp
VOLUME /tmp

# JAR file
COPY target/bookville_2-0.0.1-SNAPSHOT.jar app.jar

# Expose the port 
EXPOSE 8080

# Run the jar file
ENTRYPOINT ["java","-jar","/app.jar"]

docker-compose.yml

version: '3.8'

services:
  springboot-app:
    build: .
    ports:
      - "9090:9090"
    depends_on:
      - mysql
    environment:
      SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/dbname
      SPRING_DATASOURCE_USERNAME: root
      SPRING_DATASOURCE_PASSWORD: password

  mysql:
    image: mysql:8.0.33
    ports:
      - "3307:3306"
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: bookville
    volumes:
      - mysql-data:/var/lib/mysql

volumes:
  mysql-data:

application.properties

spring.application.name=bookville
spring.datasource.url=jdbc:mysql://mysql:3306/bookville
spring.datasource.username=root
spring.datasource.password=password
spring.jpa.hibernate.ddl-auto=update
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.show-sql=true
解决方案

1. 修复数据库名称不匹配问题

docker-compose.yml中Spring Boot服务的SPRING_DATASOURCE_URL指定的数据库是dbname,但MySQL容器初始化创建的数据库是bookville,同时application.properties里的URL也是bookville。环境变量会覆盖配置文件,导致应用尝试连接不存在的数据库,进而引发Hibernate的空指针异常。

修改docker-compose.yml中Spring Boot服务的环境变量:

SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/bookville

2. 解决MySQL启动延迟问题

depends_on仅保证容器启动顺序,不确保MySQL服务完全就绪。Spring Boot启动时若连接未就绪的MySQL,会触发连接异常,最终导致空指针。

方案A:添加启动等待脚本

在项目根目录添加wait-for-it.sh脚本(采用标准的wait-for-it实现逻辑),修改Dockerfile引入等待逻辑:

FROM openjdk:17-jdk-alpine
RUN apk add --no-cache bash
COPY wait-for-it.sh /wait-for-it.sh
RUN chmod +x /wait-for-it.sh
VOLUME /tmp
COPY target/bookville_2-0.0.1-SNAPSHOT.jar app.jar
EXPOSE 8080
ENTRYPOINT ["/wait-for-it.sh", "mysql:3306", "--", "java", "-jar", "/app.jar"]

方案B:配置连接池重试机制

在application.properties中添加连接池参数,让应用自动重试连接:

# 连接超时时间
spring.datasource.hikari.connection-timeout=60000
# 最大连接数
spring.datasource.hikari.maximum-pool-size=5
# 禁用自动提交
spring.jpa.properties.hibernate.connection.provider_disables_autocommit=true
# 连接校验
spring.datasource.test-on-borrow=true
spring.datasource.validation-query=SELECT 1

3. 统一端口配置

Dockerfile中EXPOSE 8080,但docker-compose.yml映射的是9090:9090,需确保端口一致:

  • 若应用默认监听8080,修改docker-compose.yml的端口映射为9090:8080
  • 若要使用9090端口,在application.properties中添加server.port=9090

4. Render/Railway部署提前适配

这两个平台推荐使用托管数据库服务而非容器化MySQL,优化部署流程:

  • 移除docker-compose.yml中的MySQL服务,改用平台提供的MySQL实例
  • 配置平台环境变量,替换Spring Boot的数据库连接参数(URL、用户名、密码)
  • 移除本地端口映射,平台会自动分配对外访问端口

内容的提问来源于stack exchange,提问作者Chinecherem Ubawike

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 12:02:15