【问题标题】:Hibernate JPA 2.1: OUT REF CURSOR in position other than first?Hibernate JPA 2.1:OUT REF CURSOR在第一个以外的位置?
【发布时间】:2014-05-30 04:26:39
【问题描述】:

我正在使用旧版 Oracle 数据库,其中所有存储过程都使用 OUT 参数 last 定义。 Hibernate 仅支持 first 定义了 OUT 参数的存储过程。

使用 Hibernate ORM 4.3.5,有没有办法覆盖 Hibernate 的 Oracle 驱动程序以使用 last 参数而不是 first 从 @987654322 获取值@?我已经开始使用CallableStatement,但这违背了使用 Hibernate 和 JPA 的全部目的。

这是我尝试定义@NamedNativeQuery 的方式,如果可能的话,我想坚持这个定义:

@NamedNativeQuery(
    name = "MyEntity.storedProc",
    query = "call ENTITY_PKG.StoredProc(:inputOne, :inputTwo, :resultSet)",
    callable = true,
    readOnly = true,
    resultClass = MyEntity.class
)

更新:

在跟进尼尔斯托克顿的回答后,我想出了以下@NamedStoredProcedureQuery 注释:

@NamedStoredProcedureQuery(
        name = "MyEntity.storedProc",
        procedureName = "ENTITY_PKG.StoredProc",
        resultClasses = MyEntity.class,
        parameters = {
            @StoredProcedureParameter(name = "I_INPUT_ONE", type = String.class, mode = ParameterMode.IN),
            @StoredProcedureParameter(name = "I_INPUT_TWO", type = Character.class, mode = ParameterMode.IN),
            @StoredProcedureParameter(name = "O_CURSOR", type = void.class, mode = ParameterMode.REF_CURSOR)
        }
)

但是,使用上述结果会导致此异常...java.lang.UnsupportedOperationException: org.hibernate.dialect.Oracle10gDialect does not support resultsets via stored procedures。这是堆栈跟踪:

Caused by: java.lang.UnsupportedOperationException: org.hibernate.dialect.Oracle10gDialect does not support resultsets via stored procedures
    at org.hibernate.dialect.Dialect.registerResultSetOutParameter(Dialect.java:1612)
    at org.hibernate.engine.jdbc.cursor.internal.StandardRefCursorSupport.registerRefCursorParameter(StandardRefCursorSupport.java:94)
    at org.hibernate.procedure.internal.AbstractParameterRegistrationImpl.prepare(AbstractParameterRegistrationImpl.java:298)
    at org.hibernate.procedure.internal.ProcedureCallImpl.buildOutputs(ProcedureCallImpl.java:417)
    at org.hibernate.procedure.internal.ProcedureCallImpl.getOutputs(ProcedureCallImpl.java:378)
    at org.hibernate.jpa.internal.StoredProcedureQueryImpl.outputs(StoredProcedureQueryImpl.java:251)
    at org.hibernate.jpa.internal.StoredProcedureQueryImpl.execute(StoredProcedureQueryImpl.java:234)
    at com.example.MyEntityDao.testStoredProc(MyEntityDao.java:88)

当我尝试像这样执行查询时会发生这种情况:

StoredProcedureQuery query = entityManager
        .createNamedStoredProcedureQuery("MyEntity.storedProc");

query.setParameter("I_INPUT_ONE", "inputOneValue");
query.setParameter("I_INPUT_TWO", 'x');
query.execute(); // exception is triggered by query.execute()

MyEntity myEntity = (MyEntity) query.getOutputParameterValue("O_CURSOR");

这本身并没有多大意义,因为Oracle10gDialect 确实继承了registerResultSetOutParameter() 的实现。这个方法是@Overriden by Oracle8iDialect,它是Oracle9iDialect的超类,而Oracle9iDialect又是Oracle10gDialect的超类。

我的 Hibernate 方言在 persistence.xml<properties> 部分定义:

<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />

作为参考,这是我的存储过程的规范...主体没有RETURN,所以OUT 游标是我访问结果的唯一方法。

CREATE OR REPLACE PACKAGE ENTITY_PKG IS
TYPE EntityCursor IS REF CURSOR;

PROCEDURE StoredProc
(
   I_INPUT_ONE IN ENTITIES.INPUT_ONE%TYPE, -- VARCHAR2
   I_INPUT_TWO IN ENTITIES.INPUT_TWO%TYPE, -- CHAR
   O_CURSOR OUT EntityCursor 
);

END ENTITY_PKG;

我做错了什么?

【问题讨论】:

  • Oracle 不直接支持返回ResultSet 的存储过程,但是有一个变通方法。参考here。 HTH

标签: java oracle hibernate jpa stored-procedures


【解决方案1】:

JPA 2.1 提供了一个 API 来使用存储过程,而不是将它们作为原生“查询”进行破解。也许你真的应该使用它?

【讨论】:

  • 使用 JPA 2.1、Hibernate 5.0.9、Oracle10gDialect - 我无法让存储过程 API 使用命名参数和至少一个 OUT 参数。位置似乎没问题,但只是把警告放在那里。
  • 也许您应该在自己的问题中添加问题的详细信息,因为这是针对其他人的
  • 我尝试使用 StoredProcedureQuery 但得到相同的异常,所以问题不是使用 JPA 2.1
猜你喜欢
  • 2011-10-24
  • 2014-10-26
  • 1970-01-01
  • 2017-03-10
  • 2016-01-30
  • 1970-01-01
  • 2014-05-27
  • 2021-09-25
  • 1970-01-01
相关资源
最近更新 更多