首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有PostgreSQL和REF_CURSORs的JPA2.1

带有PostgreSQL和REF_CURSORs的JPA2.1
EN

Stack Overflow用户
提问于 2015-11-10 19:11:12
回答 1查看 4.2K关注 0票数 6

我在我的PostgreSQL DB中创建了一个函数,我想使用JPA2.1的StoredProcedureQuery方法调用它。

下面是我的PostgreSQL查询:

代码语言:javascript
复制
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中调用它:

代码语言:javascript
复制
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();

当我这样做时,我会得到以下例外:

代码语言:javascript
复制
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函数添加参数会破坏它呢?

当它起作用的例子:

代码语言:javascript
复制
 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中:

代码语言:javascript
复制
StoredProcedureQuery storedProcedure =    em.createStoredProcedureQuery("get_values");
storedProcedure.registerStoredProcedureParameter(1, Object.class, ParameterMode.REF_CURSOR);
storedProcedure.execute();
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-11-10 19:59:50

简短回答:颠倒两次调用registerStoredProcedureParameter()的顺序

代码语言:javascript
复制
storedProcedure.registerStoredProcedureParameter(1, Object.class, ParameterMode.REF_CURSOR);
storedProcedure.registerStoredProcedureParameter(2, String.class, ParameterMode.IN);

长答案:我在后置可调用语句支持的Hibernate源代码中做了一些调查,发现每个registerStoredProcedureParameter()调用都创建了一个ParameterRegistrationImplementor实例,该实例被添加到列表中并传递。您将注意到,这个类存储参数的位置,它独立于它在列表中的位置。

稍后,这个列表是分析,并假设REF_CURSOR参数将是第一个行,如果REF_CURSOR参数不是第一个,则抛出错误消息,而不管参数号是多少。

做事情不是一种很好的方法(IMHO),但至少解决方法很容易:如果您交换调用的顺序,您应该会没事的。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33637704

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档