为了学习使用Oracle存储过程的Hibernate 4.1,我试图找到一个尽可能简单的工作示例: 1.没有参数传入 2. SYS_REFCURSOR作为一个返回参数
我得到的是一个例外:“org.hibernate.exception.GenericJDBCException:列索引无效”。在线搜索数小时的解决方案并没有帮助。
=============================程序
CREATE OR REPLACE PROCEDURE IFC_OWNER.JPA_APPLICATION_R_TEST
( o_result_set OUT SYS_REFCURSOR )
AS
BEGIN
OPEN o_result_set FOR
SELECT APPLICATION_ID, APP_COMMON_NM, APP_DESC, APP_URL FROM APPLICATION_R;
END;
/
============================= xml电话
<sql-query name="oracleproccall" callable="true">
<return alias="application_r" class="com.myco.entities.ApplicationR"/>
<![CDATA[ call JPA_APPLICATION_R_TEST() ]]>
</sql-query>
============================= java(调用sqlQuery.getResultList()时抛出异常)
public void run() {
EntityManager entityManager = entityManagerFactory.createEntityManager();
try {
Query sqlQuery = entityManager.createNamedQuery("oracleproccall");
List list = sqlQuery.getResultList();
...snip...
} catch (PersistenceException ex) {
ex.printStackTrace();
} finally {
entityManager.close();
}
}
=============================实体类
@Entity
@Table(name = "APPLICATION_R", schema = "IFC_OWNER")
public class ApplicationR implements Serializable {
private int applicationId;
private String appCommonNm;
private String appDesc;
private String appUrl;
...snip...
More available if needed.
=============================异常
## ApplicationsByStoredProc ##
Hibernate:
/* named native SQL query oracleproccall */ call JPA_APPLICATION_R_TEST()
Feb 19, 2013 2:58:07 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
WARN: SQL Error: 17003, SQLState: 99999
Feb 19, 2013 2:58:07 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: Invalid column index
javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: Invalid column index
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1377)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1300)
at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:266)
at com.myco.jpa.tests.ApplicationsByStoredProc.run(ApplicationsByStoredProc.java:37)
at com.dstoutput.jpa.JPAEntities_InFactDomain_Test.main(JPAEntities_InFactDomain_Test.java:56)
Caused by: org.hibernate.exception.GenericJDBCException: Invalid column index
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:54)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110)
at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:129)
at org.hibernate.engine.jdbc.internal.proxy.CallableStatementProxyHandler.continueInvocation(CallableStatementProxyHandler.java:49)
at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
at $Proxy16.registerOutParameter(Unknown Source)
at org.hibernate.dialect.Oracle8iDialect.registerResultSetOutParameter(Oracle8iDialect.java:507)
答案 0 :(得分:1)
我发现了这个问题。我使用的是Session和Query类的javax.persistence版本而不是org.hibernate版本;在Hibernate的情况下,javax.persistence不支持Oracle存储过程调用。 如果没有下面提供的import语句,差异很小。 赠品应该是使用sqlQuery.getResultList()。这是一个JPA方法调用,在Hibernate版本的Query中不存在。
import import javax.persistence.Query;
查询sqlQuery = entityManager.createNamedQuery(“oracleproccall”); List list = sqlQuery.getResultList();
使用Hibernate版本的构造是query.list()而不是query.getResultList():
import java.util.Iterator;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import com.myco.entities.ApplicationR
private void anotherTest() {
Configuration cfg = new Configuration();
cfg.configure("hibernate.cfg.xml");
SessionFactory sf = cfg.buildSessionFactory();
Session s = sf.openSession();
Transaction tx = s.beginTransaction();
List<AppR> apps;
Query namedQuery = s.getNamedQuery("oraclestoredproc");
apps = namedQuery.list();
apps = s.getNamedQuery("oraclestoredproc").list();
Iterator<ApplicationR> iterator = apps.iterator();
while (iterator.hasNext()) {
ApplicationR app = (ApplicationR) iterator.next();
System.out.print(app.getApplicationId() + " ");
System.out.print(app.getAppCommonNm() + " ");
System.out.print(app.getAppDesc() + " ");
System.out.println(app.getAppUrl() + " ");
}
s.flush();
tx.commit();
s.close();
}
感谢Jitu Ji和source