【问题标题】:Spring Boot - PostgreSQL Function Array ParameterSpring Boot - PostgreSQL 函数数组参数
【发布时间】:2019-04-19 08:41:55
【问题描述】:

当我在spring boot中使用postgresql函数时,当我使用数组参数时它返回一个数据不匹配错误。

我有一个模型文件。我正在将数据按顺序保存到此模型文件中。当我通过以下方式将其发送到函数时,出现错误。

        StoredProcedureQuery subscriber = entityManager.createStoredProcedureQuery("fn_subscriber_to_iservice");
    subscriber.registerStoredProcedureParameter(1, Integer.class, ParameterMode.IN);
    subscriber.registerStoredProcedureParameter(2, Integer.class, ParameterMode.IN);
    subscriber.registerStoredProcedureParameter(3, String.class, ParameterMode.IN);
    subscriber.registerStoredProcedureParameter(4, String.class, ParameterMode.IN);
    subscriber.registerStoredProcedureParameter(5, Double.class, ParameterMode.IN);
    subscriber.registerStoredProcedureParameter(6, Double.class, ParameterMode.IN);
    subscriber.registerStoredProcedureParameter(7, Double.class, ParameterMode.IN);
    subscriber.registerStoredProcedureParameter(8, Integer.class, ParameterMode.IN);
    subscriber.registerStoredProcedureParameter(9, Integer.class, ParameterMode.IN);
    **subscriber.registerStoredProcedureParameter(10, Object[].class, ParameterMode.IN)**;


subscriber.setParameter(1, Integer.valueOf(String.valueOf(payload.getService_id())));
    subscriber.setParameter(2, Integer.valueOf(String.valueOf(userDetail.getId())));
    subscriber.setParameter(3, String.valueOf(payload.getStart_date()));
    subscriber.setParameter(4, String.valueOf(payload.getEnd_date()));
    subscriber.setParameter(5, payload.getTotal_price());
    subscriber.setParameter(6, 0.00);
    subscriber.setParameter(7, payload.getPrice_per_person());
    subscriber.setParameter(8, Integer.valueOf(String.valueOf(payload.getStart_station_id())));
    subscriber.setParameter(9, Integer.valueOf(String.valueOf(payload.getEnd_station_id())));
    **subscriber.setParameter(10, payload.getPassengers().toArray());**

PostgreSQL 函数参数

CREATE OR REPLACE FUNCTION "public"."fn_subscriber_to_iservice"("_service_id" int4, "user_id" int4, "_start_date" varchar, "_end_date" varchar, "total_price" float8, "total_month" float8, "price_per_person" float8, "_start_station_id" int4, "_end_station_id" int4, "passengerlist" json)

错误

ERROR 15464 --- [nio-8080-exec-1] oaccC[.[.[/].[dispatcherServlet]:Servlet.service() 用于路径 [] 的上下文中的 servlet [dispatcherServlet] 引发异常 [Request处理失败;嵌套异常是 javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: Error calling CallableStatement.getMoreResults] 的根本原因 org.postgresql.util.PSQLException:错误:函数 fn_subscriber_to_iservice(整数,整数,字符变化,字符变化,双精度,双精度,双精度,整数,整数,bytea)不存在 İpucu: 没有函数匹配给定的名称和参数类型。您可能需要添加显式类型转换。 位置:15

谢谢。

【问题讨论】:

  • 您不需要“存储过程”对象来调用函数。你能告诉 Hibernate 简单地运行一个选择查询吗,例如select fn_subscriber_to_iservice(?,?...)

标签: postgresql hibernate spring-boot stored-procedures


【解决方案1】:

问题是您在此处将数组传递给json 参数:

subscriber.setParameter(10, payload.getPassengers().toArray());

您需要先将其转换为 JSON 字符串。假设该函数实际上需要乘客 ID,您可以执行以下操作。

StringBuilder ab = new StringBuilder();
ab.append('{');
for (Passenger p : payload.getPassengers()) {
    ab.append(p.getId()).append(',');
}
ab.replace(ab.length()-1, ab.length(), "}");
subscriber.setParameter(10, ab.toString());

并将函数定义的最终参数从"passengerlist" json 更改为"passengerlist" bigint[]int[],具体取决于ID 类型。这也将节省您从 json 数组到您可以使用的整数 id 的痛苦转换。

请注意,该算法描述的是 PostgreSQL 数组的字符串化版本,与其他数据库不兼容。它也没有描述包含字符串或其转义序列的数组。这个简单的版本只适用于数值。

如果没有将自动类型转换函数从字符串注册到给定类型,这最终也可能不起作用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-28
    • 1970-01-01
    • 2022-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-18
    相关资源
    最近更新 更多