首页 > 解决方案 > Spring Boot - PostgreSQL 函数数组参数

问题描述

当我在 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)

错误

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

谢谢。

标签: postgresqlhibernatespring-bootstored-procedures

解决方案


问题是您在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());

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

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

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


推荐阅读