Java JPA 2.1带PostgreSQL和REF_游标的StoredProcedureQuery

Java JPA 2.1带PostgreSQL和REF_游标的StoredProcedureQuery,java,hibernate,postgresql,jpa,Java,Hibernate,Postgresql,Jpa,我在PostgreSQL数据库中创建了一个函数,我想使用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(*)

我在PostgreSQL数据库中创建了一个函数,我想使用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使用时,它就可以正常工作

现在,让我们试着使用JPA 2.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
只声明了一个ref游标!事实上,如果我只是为WHERE date=date注册一个REF\u CURSOR参数和一个Postgresql函数值的硬代码,那么这个调用就可以正常工作

因此,使用ref_光标向storedprocedurequery添加任何附加参数似乎都会破坏该功能。仅ref_游标参数就可以正常工作

有人知道为什么会发生这种情况吗??为什么在我的PostgreSQL函数的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
在爪哇岛:

StoredProcedureQuery storedProcedure =    em.createStoredProcedureQuery("get_values");
storedProcedure.registerStoredProcedureParameter(1, Object.class, ParameterMode.REF_CURSOR);
storedProcedure.execute();

简短回答:颠倒对注册表存储过程参数()的两次调用顺序。:

详细回答:我在中做了一些挖掘,发现每个
registerStoredProcedureParameter()
调用都会创建一个实例,该实例会被添加到列表中并传递。您将注意到,此类存储参数的位置,该位置独立于其在列表中的位置

稍后,此列表为,并假设
REF\u CURSOR
参数将在第一行,如果
REF\u CURSOR
参数不是第一个,则抛出错误消息,而不管参数编号是什么


这不是一种很好的做事方式(IMHO),但至少解决方法很简单:如果您交换通话顺序,您应该会没事。

让我试试这个,然后再回复您!
storedProcedure.registerStoredProcedureParameter(1, Object.class, ParameterMode.REF_CURSOR);
storedProcedure.registerStoredProcedureParameter(2, String.class, ParameterMode.IN);