我正在使用旧版 Oracle 数据库,其中所有存储过程都是使用 OUT 参数 last 定义的。 Hibernate 仅支持首先定义了 OUT 参数的存储过程。
使用 Hibernate ORM 4.3.5,有没有办法覆盖 Hibernate 的 Oracle 驱动程序以使用 last 参数而不是 first 从 @NamedNativeQuery
获取值?我已经开始使用 CallableStatement
,但这违背了使用 Hibernate 和 JPA 的全部目的。
这是我尝试定义我的 @NamedNativeQuery
的方式,如果可能的话我想坚持这个定义:
@NamedNativeQuery(
name = "MyEntity.storedProc",
query = "call ENTITY_PKG.StoredProc(:inputOne, :inputTwo, :resultSet)",
callable = true,
readOnly = true,
resultClass = MyEntity.class
)
更新:
在跟进 Neil Stockton 的回答后,我想到了以下 @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()
的实现。这个方法是 @Override
的 Oracle8iDialect
n,它是 Oracle9iDialect
的父类(super class),而 Oracle10gDialect
又是 <properties>
的父类(super class)。
我的 Hibernate 方言是在 persistence.xml
的 RETURN
部分定义的:
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
供引用,这是我的存储过程的规范...主体没有 OUT
,因此 ojit_code 游标是我访问结果的唯一方式。
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;
我做错了什么?
最佳答案
JPA 2.1 提供了一个 API 来使用存储过程,而不是将它们作为 native “查询”进行破解。也许你真的应该使用它?
关于java - hibernate JPA 2.1 : OUT REF CURSOR in position other than first?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23090116/