当前位置: 首页 > 面试题库 >

带有PostgreSQL和REF_CURSOR的JPA 2.1 StoredProcedureQuery

乜建柏
2023-03-14
问题内容

我在PostgreSQL数据库中创建了一个函数,希望使用JPA 2.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的Postgresql函数的值中注册单个REF_CURSOR参数和硬编码,则此调用可以正常进行。

因此,使用ref_cursor向存储过程查询中添加任何其他参数似乎破坏了功能。单独使用ref_cursor参数可以正常工作。

有人看到为什么会这样吗? 为什么为我的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

在javaland中:

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

问题答案:

简短答案:将您的两个呼叫顺序颠倒为registerStoredProcedureParameter()

storedProcedure.registerStoredProcedureParameter(1, Object.class, ParameterMode.REF_CURSOR);
storedProcedure.registerStoredProcedureParameter(2, String.class, ParameterMode.IN);

长答案:我对Hibernate源代码进行了一些挖掘,以获取Postgress可调用语句支持,并发现每个registerStoredProcedureParameter()调用都创建了一个ParameterRegistrationImplementor实例,该实例被添加到列表中并传递。您会注意到,此类存储了参数的位置,该位置与其在列表中的位置无关。

稍后,将分析此列表,并假定REF_CURSOR参数将排在第一位,并且如果REF_CURSOR参数不是第一个参数(
无论参数号是) 将抛出错误消息。

这不是一个非常聪明的处事方式(IMHO),但至少解决方法很简单:如果交换呼叫顺序,就可以了。



 类似资料:
  • 问题内容: 有一种简单的方法可以将hibernate设置为对每个带有postgres的表使用不同的主键ID。我试图在数据源中使用postgres方言: 但这是行不通的。谢谢 问题答案: 简短的答案是没有,没有 简单的 方法可以做到这一点。但是,我找到了一种有效的解决方案。基本上,您需要实现自定义方言。这是一个实现(请在注释中注明实现的原始来源)。 上述实施应当存储为下你的Grails项目中。 接下

  • 我在设置docker映像时遇到了一些问题,该映像最终将用于bitbucket管道,以便为我从事的一些API项目运行测试。 我们本地开发人员的设置非常简单,在机器上运行Java 8 Maven PostgreSQL 9.6。 要运行集成测试,必须运行数据库。maven构建的一部分在服务器上创建必要的数据库和表。 我试图在docker映像上复制它,这是我到目前为止所拥有的。 如果我通过first ru

  • 我正在编写一个脚本,它查询一些设备并将数据写入PostgreSQL数据库。

  • 问题内容: 我使用Vlad Mihalcea的库来将SQL数组(在我的情况下为Postgresql)映射到JPA。然后,假设我有一个实体,例如。 适当的SQL是: 使用QueryDSL,我想获取包含所有给定标签的行。原始SQL可能是: (摘自:https : //www.postgresql.org/docs/9.1/static/functions- array.html ) 可以用QueryD

  • 如果我用ctx.insertinto来做这个...很好用。我最初使用的是Jooq3.14.0,但升级到最新的3.14.4对此没有帮助。生成的Keys类一定有问题,因为在初始化Keys类之前一切都正常工作。是Postgresql表结构出了问题,还是代码生成出了问题? 完整回购如下:https://github.com/eriran/criminal-api/tree/security-tumpt

  • 问题内容: 我正在尝试使用PostgreSQL 9.2中添加的功能将查询结果映射到JSON 。 我在找出将连接的行表示为嵌套对象(1:1关系)的最佳方式时遇到麻烦 这是我尝试过的内容(设置代码:表格,示例数据,后跟查询): 查询本身: 我发现如果使用,我可以将结果字段分离为一个子对象,但似乎仅限于一个级别。我不能插入更多的语句,因为我认为在这种情况下我需要。 为我提供了列名,因为在该表的结果中,我