创建Spring Boot Jar的Docker镜像时遇数据库连接及方言识别错误求助
问题描述
Spring Boot项目集成Spring MVC、Spring JPA与MySQL,本地运行Jar文件无异常,但构建Docker镜像并执行docker run启动容器时出现报错:无法连接MySQL获取JDBC元数据,无法确定Hibernate Dialect,导致EntityManagerFactory创建失败。尝试复制本地JDK路径到镜像也失败。
Dockerfile
FROM openjdk:17-jdk-alpine WORKDIR /app COPY target/demo-0.0.1-SNAPSHOT.jar /app/demo-0.0.1-SNAPSHOT.jar EXPOSE 8080 CMD [ "java","-jar","/app/demo-0.0.1-SNAPSHOT.jar" ]
Application.properties
spring.application.name=demo spring.datasource.url= jdbc:mysql://localhost:3306/demo spring.datasource.username= root spring.datasource.password= admin spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=create #spring.jpa.properties.hibernate.boot.allow_jdbc_metadata_access=false server.port= 1001 #spring.devtools.restart.enabled= true #spring.devtools.livereload.enabled= true #spring.main.log-startup-info= false #spring.devtools.restart.enabled= true spring.main.lazy-initialization= true
关键错误日志
2024-08-27T14:52:10.818Z WARN 1 --- [demo] [ main] o.h.e.j.e.i.JdbcEnvironmentInitiator : HHH000342: Could not obtain connection to query metadata 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 ... 2024-08-27T14:52:10.830Z ERROR 1 --- [demo] [ main] j.LocalContainerEntityManagerFactoryBean : Failed to initialize JPA EntityManagerFactory: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] due to: Unable to determine Dialect without JDBC metadata (please set 'jakarta.persistence.jdbc.url' for common cases or 'hibernate.dialect' when a custom Dialect implementation must be provided)
尝试的错误操作
添加以下Dockerfile指令时出现COPY错误:
COPY C:/Program Files/Java/jdk-21/bin /usr/local/bin/
解决方案
1. 修正数据库连接地址
容器内的localhost指向容器自身,而非宿主机的MySQL服务,需修改spring.datasource.url:
- Docker Desktop(Windows/macOS)环境:替换为
jdbc:mysql://host.docker.internal:3306/demo - Linux环境:替换为宿主机实际IP地址(如
192.168.1.100):jdbc:mysql://192.168.1.100:3306/demo - 规范方案:创建Docker自定义网络,将MySQL容器与应用容器加入同一网络,用MySQL容器名作为地址:
jdbc:mysql://mysql-container-name:3306/demo
2. 移除无效的本地JDK复制操作
基础镜像openjdk:17-jdk-alpine已自带JDK环境,无需复制本地JDK;且Docker构建上下文无法直接访问宿主机C盘路径,直接删除该COPY指令即可。
3. 可选:显式指定Hibernate方言
避免依赖JDBC元数据自动识别方言,在application.properties中添加:
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
(根据MySQL版本调整,MySQL5.x版本可使用org.hibernate.dialect.MySQL5Dialect)
内容的提问来源于stack exchange,提问作者Abrar
相关产品推荐
相关产品推荐

