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

Spring Boot仓库测试中H2缺失PostgreSQL函数引发InvalidDataAccessResourceUsageException

解决方案

方案1:在H2中自定义DATE_PART函数

H2支持通过SQL自定义函数模拟PostgreSQL专属函数,可在测试初始化阶段执行脚本创建:

  1. 创建初始化脚本(比如src/test/resources/init-h2-functions.sql):
CREATE ALIAS DATE_PART FOR "com.yourpackage.H2FunctionUtils.datePart";
  1. 编写Java工具类实现函数逻辑(匹配PostgreSQL周计算规则,默认周一起始、周数从1开始):
package com.yourpackage;

import java.sql.Date;
import java.time.LocalDate;
import java.time.temporal.WeekFields;
import java.util.Locale;

public class H2FunctionUtils {
    public static long datePart(String part, Date date) {
        if ("week".equalsIgnoreCase(part)) {
            LocalDate localDate = date.toLocalDate();
            WeekFields weekFields = WeekFields.of(Locale.ENGLISH);
            return localDate.get(weekFields.weekOfWeekBasedYear());
        }
        // 可扩展支持year、month等其他DATE_PART参数
        throw new UnsupportedOperationException("Unsupported part: " + part);
    }
}
  1. 在测试类中加载脚本:
@DataJpaTest
@Sql(scripts = "/init-h2-functions.sql")
public class FraudReviewEventRepositoryTest {
    // 原有测试逻辑保持不变
}

方案2:升级H2版本至原生兼容DATE_PART的版本

H2 2.1.210及以上版本在PostgreSQL兼容模式下已原生支持DATE_PART函数,直接升级依赖即可:

Maven依赖示例:

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>2.2.224</version>
    <scope>test</scope>
</dependency>

Gradle依赖示例:

testImplementation 'com.h2database:h2:2.2.224'

升级后保持原JDBC URL配置(MODE=PostgreSQL),无需修改查询代码。

方案3:用H2的EXTRACT函数分环境替换查询

如果仅需支持week参数,可通过Spring Profile区分生产与测试环境的查询:

  1. 生产环境Repository(保留PostgreSQL原生查询):
@Repository
@Profile("!test")
public interface MyEntityRepositoryProd extends JpaRepository<MyEntity, Long>, JpaSpecificationExecutor<MyEntity> {
    @Query(value =
            "SELECT * FROM my_entity t " +
            "WHERE t.column = :val1 " +
            "AND DATE_PART('week', t.date_column) = :val2",
        nativeQuery = true)
    List<MyEntity> fooBar(Long val1, Long val2);
}
  1. 测试环境Repository(使用H2兼容的EXTRACT函数):
@Repository
@Profile("test")
public interface MyEntityRepositoryTest extends JpaRepository<MyEntity, Long>, JpaSpecificationExecutor<MyEntity> {
    @Query(value =
            "SELECT * FROM my_entity t " +
            "WHERE t.column = :val1 " +
            "AND EXTRACT(WEEK FROM t.date_column) = :val2",
        nativeQuery = true)
    List<MyEntity> fooBar(Long val1, Long val2);
}

需确保测试环境激活test Profile,比如在application-test.properties中添加spring.profiles.active=test。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 02:05:18