Spring Boot 3.1.2集成测试H2/PostgreSQL配置失败,DataJpaTest可运行
Spring Boot 3.1.2升级后Hibernate DDL适配问题
基础环境
- JDK版本:17
- Spring Boot版本:从2.7.11升级至3.1.2
- 数据库配置:生产环境用PostgreSQL(驱动版本42.6.0),测试环境用H2(版本2.1.214)并设置
MODE=PostgreSQL,未显式配置Hibernate方言
项目架构与测试流程
- 多模块架构,独立模块提供持久层访问,定义多个实体类
- 数据库初始化工具:Liquibase 4.23.0
- 测试执行逻辑:先由Liquibase搭建数据库结构,再由Hibernate执行
create-drop策略删除并重建表
测试代码与配置
集成测试代码
package my.service; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Profile; import org.springframework.context.annotation.PropertySource; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit.jupiter.SpringExtension; @ExtendWith(SpringExtension.class) @SpringBootTest @ActiveProfiles("test") class MyInternalServiceTest { @Autowired private MyInternalService myInternalService; @Test public void aVeryWellDesignedTest() { /* something */ } @ComponentScan(basePackages = "my") @EnableJpaRepositories(basePackages = "my.persistence") @EntityScan(basePackages = "my.persistence") @SpringBootApplication @Profile("test") @PropertySource("classpath:application-test.yml") static class TestConfiguration {} }
测试环境配置(application-test.yml)
spring: datasource: driver-class-name: org.h2.Driver username: sa password: url: jdbc:h2:mem:tests;DB_CLOSE_DELAY=-1;MODE=PostgreSQL;DB_CLOSE_ON_EXIT=FALSE jpa: hibernate: ddl-auto: create-drop main: allow-bean-definition-overriding: true
升级后问题现象
在Spring Boot 2.7.11版本中,测试可正常启动:Liquibase完成数据库初始化后,Hibernate成功重建表结构,测试顺利执行。
升级至3.1.2后,Hibernate无法正确识别目标数据库,生成的DDL语句不兼容H2/PostgreSQL环境,具体问题包括:
- 枚举属性生成
TINYINT类型列(H2的PostgreSQL模式不支持该类型) - Long类型字段生成
BIGINT列,结合其他操作引发异常 - 无法删除包含外键关联的表
- 序列创建或调用语句错误
示例报错信息:
UPDATE SUMMARY Run: 73 Previously run: 0 Filtered out: 0 ------------------------------- Total change sets: 73 Liquibase: Die Update-Operation war erfolgreich. 2023-08-13T09:21:50.571+02:00 WARN 10865 --- [main] o.h.t.s.i.ExceptionHandlerLoggedImpl : GenerationTarget encountered exception accepting command : Error executing DDL "create table inouthistory (active boolean, geoeventsource integer, geofencestatus tinyint check (geofencestatus between 0 and 5), geotimestamp timestamp(6), id bigint not null, lastupdatetime timestamp(6), vehicleid bigint, primary key (id))" via JDBC [Unbekannter Datentyp: "TINYINT" Unknown data type: "TINYINT";]
注:"Liquibase: Die Update-Operation war erfolgreich."意为“Liquibase:更新操作执行成功”
尝试的临时方案与疑问
将@SpringBootTest替换为@DataJpaTest后,Hibernate可正常处理表的删除与重建,但测试会在应用上下文启动阶段失败。
曾认为这是Spring Boot的bug,但官方团队不认可该观点,因此推测可能存在配置疏漏。另外怀疑该问题与Spring Boot 3.1.2集成测试会加载其他测试的@Configuration类至应用上下文有关,但仅为猜测。
内容的提问来源于stack exchange,提问作者kniffte
相关产品推荐
相关产品推荐

