我在我的PostgreSQL DB中创建了一个函数,我想使用JPA2.1的StoredProcedureQuery方法调用它。
下面是我的PostgreSQL查询:
CREATE OR REPLACE FUNCTION get_values(date text) returns refcursor
AS $$
DECLARE tuples refcursor;
BEGIN OPEN tuples FOR
SELECT user, COUNT(*)
FROM my_table
WHERE date_ = date
GROUP BY user;
return tuples;
END;
$$
LANGUAGE plpgsql这只是一个简单的查询,可以在特定的一天统计用户。这只是一个测试StoredProcedureQueries如何工作的演示查询。事实上,如果仅通过postgreSQL使用,它就会工作得很好。
现在,让我们尝试使用JPA2.1并在Javaland中调用它:
StoredProcedureQuery storedProcedure = em.createStoredProcedureQuery("get_values");
storedProcedure.registerStoredProcedureParameter(2, String.class, ParameterMode.IN);
storedProcedure.registerStoredProcedureParameter(1, Object.class, ParameterMode.REF_CURSOR);
storedProcedure.setParameter(2, "2015-02-01");
storedProcedure.execute();当我这样做时,我会得到以下例外:
org.hibernate.HibernateException: PostgreSQL supports only one REF_CURSOR parameter, but multiple were registered只有一个引用游标声明!实际上,如果我只是为WHERE REF_CURSOR = date在Postgresql函数的值中注册单个date_参数和硬代码,那么这个调用就能正常工作。
因此,似乎在存储过程中添加任何附加参数都会破坏ref_cursor的功能。单是ref_cursor参数就可以正常工作。
有人知道为什么会发生这种事吗??为什么为我的StoredProcedureQuery函数添加参数会破坏它呢?
当它起作用的例子:
CREATE OR REPLACE FUNCTION get_values(date text) returns refcursor
AS $$
DECLARE tuples refcursor;
BEGIN OPEN tuples FOR
SELECT user, COUNT(*)
FROM my_table
WHERE date_ = '2015-02-01'
GROUP BY user;
return tuples;
END;
$$
LANGUAGE plpgsql在javaland中:
StoredProcedureQuery storedProcedure = em.createStoredProcedureQuery("get_values");
storedProcedure.registerStoredProcedureParameter(1, Object.class, ParameterMode.REF_CURSOR);
storedProcedure.execute();发布于 2015-11-10 19:59:50
简短回答:颠倒两次调用registerStoredProcedureParameter()的顺序
storedProcedure.registerStoredProcedureParameter(1, Object.class, ParameterMode.REF_CURSOR);
storedProcedure.registerStoredProcedureParameter(2, String.class, ParameterMode.IN);长答案:我在后置可调用语句支持的Hibernate源代码中做了一些调查,发现每个registerStoredProcedureParameter()调用都创建了一个ParameterRegistrationImplementor实例,该实例被添加到列表中并传递。您将注意到,这个类存储参数的位置,它独立于它在列表中的位置。
稍后,这个列表是分析,并假设REF_CURSOR参数将是第一个行,如果REF_CURSOR参数不是第一个,则抛出错误消息,而不管参数号是多少。
做事情不是一种很好的方法(IMHO),但至少解决方法很容易:如果您交换调用的顺序,您应该会没事的。
https://stackoverflow.com/questions/33637704
复制相似问题