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

通过Hibernate调用PostgreSQL函数时的日期类型转换问题

解决Hibernate调用PostgreSQL函数时的日期类型不匹配问题

你遇到的核心问题是PostgreSQL对函数参数的类型匹配要求严格,而Hibernate默认的日期类型映射和函数期望的date类型不匹配,导致数据库找不到对应的函数签名。下面是具体的分析和解决方案:

问题根源

直接执行SQL时,你传入的'1-nov-2019'这类字符串会被PostgreSQL自动解析为date类型;但通过Hibernate传递java.util.Date时,Hibernate默认会把它映射为PostgreSQL的timestamp类型(因为java.util.Date包含时间信息),而你的函数property.fn_pt_assessment_register_report的第二、第三个参数定义为date类型,数据库因此找不到参数类型完全匹配的函数,抛出ERROR: function ... does not exist的错误。

解决方案

方案1:在Hibernate中显式指定参数为SQL DATE类型

你可以在设置参数时,明确告诉Hibernate要把java.util.Date转换为PostgreSQL的date类型:

Session session = sessionFactory.getCurrentSession();
StoredProcedureQuery query = session 
    .createStoredProcedureQuery("property.fn_pt_assessment_register_report")
    .registerStoredProcedureParameter(1, Integer.class, ParameterMode.IN)
    .registerStoredProcedureParameter(2, java.util.Date.class, ParameterMode.IN)
    .registerStoredProcedureParameter(3, java.util.Date.class, ParameterMode.IN)
    .setParameter(1, (int)qryprm.get("ULBID"))
    // 显式指定SQL类型为DATE
    .setParameter(2, ((java.util.Date)qryprm.get("FROMDATE")), Types.DATE)
    .setParameter(3, ((java.util.Date)qryprm.get("TODATE")), Types.DATE);
Boolean b = query.execute();
return query.getResultList();

或者在注册参数阶段就指定对应的SQL类型名称:

.registerStoredProcedureParameter(2, java.util.Date.class, ParameterMode.IN, "date")
.registerStoredProcedureParameter(3, java.util.Date.class, ParameterMode.IN, "date")

方案2:改用java.sql.Date代替java.util.Date

java.sql.Date是专门对应SQL中date类型的类,不包含时间部分,能直接匹配PostgreSQL的date参数。修改你的日期转换代码:

SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
try {
    Date utilFromDate = sdf.parse((String)qryprm.get("FROMDATE"));
    Date utilToDate = sdf.parse((String)qryprm.get("TODATE"));
    // 转换为java.sql.Date,丢弃时间部分
    qryprm.put("FROMDATE", new java.sql.Date(utilFromDate.getTime()));
    qryprm.put("TODATE", new java.sql.Date(utilToDate.getTime()));
} catch (ParseException e1) {
    e1.printStackTrace();
}

然后更新Hibernate参数注册的类型:

StoredProcedureQuery query = session 
    .createStoredProcedureQuery("property.fn_pt_assessment_register_report")
    .registerStoredProcedureParameter(1, Integer.class, ParameterMode.IN)
    .registerStoredProcedureParameter(2, java.sql.Date.class, ParameterMode.IN)
    .registerStoredProcedureParameter(3, java.sql.Date.class, ParameterMode.IN)
    .setParameter(1, (int)qryprm.get("ULBID"))
    .setParameter(2, ((java.sql.Date)qryprm.get("FROMDATE")))
    .setParameter(3, ((java.sql.Date)qryprm.get("TODATE")));

方案3:使用原生SQL并显式转换日期类型

如果上面的方法都不生效,你可以改用原生SQL查询,在SQL中显式把参数转换为date类型:

Session session = sessionFactory.getCurrentSession();
String sql = "select * from property.fn_pt_assessment_register_report(?, cast(? as date), cast(? as date))";
Query query = session.createNativeQuery(sql)
    .setParameter(1, (int)qryprm.get("ULBID"))
    .setParameter(2, ((java.util.Date)qryprm.get("FROMDATE")))
    .setParameter(3, ((java.util.Date)qryprm.get("TODATE")));
return query.getResultList();

前置验证步骤

在尝试解决方案前,建议先确认你的PostgreSQL函数参数类型是否确实为date:
在psql中执行命令:

\df property.fn_pt_assessment_register_report

查看函数的参数列表,确保第二、第三个参数类型是date而非timestamp或其他类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:51:51