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

Spring Boot JAR部署Docker时出现H2 SQL语法错误问题

Spring Boot Docker容器启动时误用H2数据库导致Flyway迁移SQL语法错误

我有一个Spring Boot项目,本地使用MySQL数据库,仅测试环境使用H2数据库。项目本地编译、启动均正常,但将JAR包通过Dockerfile打包到容器后启动时,出现异常:明明生产环境未启用H2,却触发了H2的SQL语法错误。Flyway执行迁移时,在创建Quartz的QRTZ_JOB_DETAILS表的语句处报错,错误信息如下:

Error; (Works in mysql on app startup and is a generic quartz copy paste configuration)
2023-02-23T04:42:07.489897039Z Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement "CREATE TABLE QRTZ_JOB_DETAILS\000d\000a(\000d\000a SCHED_NAME VARCHAR(120) NOT NULL,\000d\000a JOB_NAME VARCHAR(200) NOT NULL,\000d\000a JOB_GROUP VARCHAR(200) NOT NULL,\000d\000a DESCRIPTION VARCHAR(250) NULL,\000d\000a JOB_CLASS_NAME VARCHAR(250) NOT NULL,\000d\000a IS_DURABLE BOOLEAN NOT NULL,\000d\000a IS_NONCONCURRENT BOOLEAN NOT NULL,\000d\000a IS_UPDATE_DATA BOOLEAN NOT NULL,\000d\000a REQUESTS_RECOVERY BOOLEAN NOT NULL,\000d\000a JOB_DATA BLOB NULL,\000d\000a PRIMARY KEY (SCHED_NAME, JOB_NAME, JOB_GROUP)\000d\000a) ENGINE[*]=InnoDB"; expected "identifier"; SQL statement:

已尝试以下操作但未解决:

  • 清理构建产物
  • 指定H2方言

项目配置文件及Dockerfile

application.properties

spring.jpa.hibernate.ddl-auto=validate
spring.flyway.enabled=true
spring.flyway.baseline-on-migrate=true
spring.flyway.table=flyway_order_schema_history
#spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/cf?enabledTLSProtocols=TLSv1.2&useSSL=false&useServerPrepStmts=true
spring.datasource.url=jdbc:mysql://docker.for.win.localhost:3306/cf?enabledTLSProtocols=TLSv1.2&useSSL=false&useServerPrepStmts=true
spring.jpa.database=mysql
spring.profiles.include=quartz
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
logging.level.org.hibernate.SQL=debug
logging.level.org.hibernate.type.descriptor.sql=trace
server.port=8020
management.server.port=8029

application-test.properties

spring.main.allow-bean-definition-overriding=true
spring.application.name="cf-ms-test-runner"
spring.data.jpa.repositories.enabled=true
spring.profiles.active=test
spring.flyway.enabled=false
spring.jpa.hibernate.ddl-auto=create
server.servlet.context-path=/api/v1
spring.jpa.database=H2
spring.mvc.pathmatch.matching-strategy=ANT_PATH_MATCHER
spring.jackson.default-property-inclusion=NON_NULL
spring.datasource.driverClassName=org.h2.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.HSQLDialect
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
spring.datasource.url=jdbc:h2:mem:skel;MODE=MySQL;IGNORECASE=TRUE
spring.datasource.username=sa
spring.datasource.password=

Dockerfile

FROM openjdk:11.0.11-jre
VOLUME /tmp
COPY build/libs/*.jar  app.jar
ENTRYPOINT ["java","-jar","app.jar"]

问题根源

容器启动时,项目意外加载了H2数据库驱动或配置,导致Flyway用H2执行了MySQL语法的SQL(比如ENGINE=InnoDB是MySQL专属语法,H2不支持)。

解决步骤

  1. 显式指定生产环境配置启动容器
    Docker默认加载application.properties,但可能存在配置优先级问题,启动时显式指定环境:

    docker run -e SPRING_PROFILES_ACTIVE=prod your-image-name
    

    若未定义prod配置,确保application.properties完全指向MySQL,无任何H2相关依赖或配置。

  2. 限制H2依赖仅在测试环境生效
    确保H2依赖仅在test scope下引入,避免打包到生产JAR:

    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>test</scope>
    </dependency>
    
    testImplementation 'com.h2database:h2'
    
  3. 修正测试环境配置冲突
    application-test.properties中同时指定MySQL方言和H2驱动,存在冲突,修改为:

    spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
    
  4. 检查容器启动时的环境变量
    确认Docker启动脚本或docker-compose.yml中未设置SPRING_PROFILES_ACTIVE=test,如有则移除。

  5. 清理Docker镜像缓存
    重新构建镜像,避免旧缓存影响:

    docker build --no-cache -t your-image-name .
    

内容的提问来源于stack exchange,提问作者User Unknown

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 20:27:19