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

Spring Boot集成测试:H2模拟PostgreSQL+Flyway加载初始数据失败

解决H2模拟PostgreSQL+Flyway加载初始数据时的连接拒绝问题

问题场景

做集成测试时需要用H2模拟PostgreSQL,结合Flyway加载初始数据,但运行时直接报错连接localhost:5432被拒绝,相关配置和报错信息如下:

配置文件

build.gradle

implementation 'org.flywaydb:flyway-core:9.19.1'
implementation 'org.postgresql:postgresql:42.6.0'
...
runtimeOnly 'com.h2database:h2:2.1.214'

application-dev.properties

#1st approach 
#spring.datasource.url=jdbc:postgresql://localhost:5432/configdb
#spring.datasource.driverClassName=org.postgresql.Driver
#spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL8Dialect

#2nd approach
spring.datasource.url=jdbc:h2:mem:configdb;DB_CLOSE_DELAY=-1;MODE=PostgreSQL
spring.datasource.driverClassName=org.h2.Driver

spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=none

spring.flyway.schemas=config
spring.flyway.locations=classpath:db

项目根目录flyway.conf

flyway.user=postgres
flyway.password=postgres
flyway.schemas=config
#flyway.url=jdbc:postgresql://localhost:5432/configdb
flyway.url=jdbc:h2:mem:configdb
flyway.locations=classpath:db

resources/db/V1__CreateConfigTable.sql

CREATE TABLE configdb.config
(
    id   bigint PRIMARY KEY,
    ...
);

-- INSERT query

报错信息

Caused by: org.flywaydb.core.internal.exception.FlywaySqlException: Unable to obtain connection from database: Connection to localhost:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.

问题根源

  1. 配置冲突:Spring Boot中Flyway的配置优先级可能被其他配置源覆盖,比如独立的flyway.conf和application-dev.properties不一致,或系统环境变量残留PostgreSQL连接信息,导致Flyway误用错误连接。
  2. H2配置不完整:仅设置MODE=PostgreSQL但缺少兼容参数,且JPA使用H2方言,导致SQL解析行为和PostgreSQL不一致。
  3. SQL脚本表名错误:脚本中写的configdb.config与指定的Flyway schemaconfig不匹配,H2中不存在configdb库,执行脚本失败后Flyway可能 fallback 到旧的PostgreSQL配置。
  4. Flyway未绑定Spring数据源:Flyway可能未使用Spring配置的H2数据源,而是自行加载了旧的PostgreSQL连接配置。

修复步骤

1. 统一Flyway与Spring数据源配置

直接在application-dev.properties中绑定Flyway和Spring数据源,避免独立配置文件的冲突:

# 补全H2兼容PostgreSQL的参数
spring.datasource.url=jdbc:h2:mem:configdb;DB_CLOSE_DELAY=-1;MODE=PostgreSQL;DATABASE_TO_UPPER=false
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=postgres
spring.datasource.password=postgres

# JPA改用PostgreSQL方言,提升H2模拟准确性
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=none

# Flyway绑定Spring数据源,确保使用同一份连接配置
spring.flyway.enabled=true
spring.flyway.schemas=config
spring.flyway.locations=classpath:db
spring.flyway.url=${spring.datasource.url}
spring.flyway.user=${spring.datasource.username}
spring.flyway.password=${spring.datasource.password}

加DATABASE_TO_UPPER=false是为了让H2不自动将表名转为大写,和PostgreSQL保持一致;切换PostgreSQL方言能让JPA生成的SQL更贴合PostgreSQL语法。

2. 删除或同步flyway.conf

要么直接删除项目根目录的flyway.conf,让Flyway完全依赖Spring配置;如果必须保留,需将其中的配置与application-dev.properties完全同步,避免冲突。

3. 修正SQL脚本的表名

脚本中的configdb.config不符合指定的schema,调整为config schema,并预先创建schema防止报错:

-- 先创建schema,确保存在
CREATE SCHEMA IF NOT EXISTS config;

CREATE TABLE config.config
(
    id   bigint PRIMARY KEY,
    ...
);

-- INSERT query

4. 确保启动时使用dev配置

启动应用时必须添加spring.profiles.active=dev参数,否则会加载默认配置,可能又切换到PostgreSQL连接。

5. 调整PostgreSQL依赖范围

将postgresql依赖改为runtimeOnly,避免测试环境下优先加载PostgreSQL驱动,干扰H2的使用:

implementation 'org.flywaydb:flyway-core:9.19.1'
runtimeOnly 'org.postgresql:postgresql:42.6.0'
...
runtimeOnly 'com.h2database:h2:2.1.214'

验证

启动后查看Flyway日志,若显示成功执行迁移脚本;开启H2控制台后能看到config schema及对应表,即说明问题解决。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 06:45:11