簡體   English   中英

JPA / Hibernate:使用輸入和輸出參數調用存儲過程

[英]JPA / Hibernate : call stored procedure with input and output parameters

我在用JPA調用Java中的排序過程時遇到問題

這是Java代碼:

    StoredProcedureQuery storedProcedureQuery = getEntityManager().createNamedStoredProcedureQuery("RECPOCH");

storedProcedureQuery.setParameter(Pochette.SP_RECPOCH_PARAM_STRSTARTSIM, pochetteCriteria.getDebutNumPochette());
storedProcedureQuery.setParameter(Pochette.SP_RECPOCH_PARAM_STRLASTSIM, pochetteCriteria.getFinNumPochette());
storedProcedureQuery.setParameter(Pochette.SP_RECPOCH_PARAM_NACTELID, pochetteCriteria.getActelId());

storedProcedureQuery.execute();
Integer result = (Integer) storedProcedureQuery.getOutputParameterValue(Pochette.SP_RECPOCH_PARAM_NRESULT);

return Long.valueOf(result);

這是代碼Oracle:

"RECPOCH" ( NACTELID IN NUMBER, STRSTARTSIM IN VARCHAR, STRLASTSIM IN VARCHAR, NRESULT OUT INTEGER )

跟蹤異常:

13:24:40.295 [http-nio-8080-exec-6] DEBUG o.s.orm.jpa.JpaTransactionManager - Participating in existing transaction
Hibernate: {call RECPOCH(?,?,?,?)}
javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: Error calling CallableStatement.getMoreResults
    at org.hibernate.jpa.internal.StoredProcedureQueryImpl.execute(StoredProcedureQueryImpl.java:230)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)
Caused by: org.hibernate.exception.GenericJDBCException: Error calling CallableStatement.getMoreResults
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:111)
    at org.hibernate.jpa.internal.StoredProcedureQueryImpl.execute(StoredProcedureQueryImpl.java:223)
    ... 90 more
Caused by: java.sql.SQLException: Le nombre de noms de paramètre ne concorde pas avec celui des paramètres inscrits
    at oracle.jdbc.driver.OracleSql.setNamedParameters(OracleSql.java:198)
    at org.apache.tomcat.dbcp.dbcp2.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:197)
13:24:40.833 [http-nio-8080-exec-6] DEBUG o.s.orm.jpa.JpaTransactionManager - Initiating transaction commit
    at org.apache.tomcat.dbcp.dbcp2.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:197)
13:24:40.833 [http-nio-8080-exec-6] DEBUG o.s.orm.jpa.JpaTransactionManager - Committing JPA transaction on EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@6db6eb5c]
    at com.zaxxer.hikari.pool.ProxyPreparedStatement.execute(ProxyPreparedStatement.java:44)
    at com.zaxxer.hikari.pool.HikariProxyCallableStatement.execute(HikariProxyCallableStatement.java)
    at org.hibernate.result.internal.OutputsImpl.(OutputsImpl.java:52)
    ... 95 more

實體中的命名排序過程定義:

    @NamedStoredProcedureQueries({
            @NamedStoredProcedureQuery(name = Pochette.SP_RECPOCH_NAME, procedureName = "RECPOCH", parameters = {
                    @StoredProcedureParameter(name = Pochette.SP_RECPOCH_PARAM_NRESULT, mode = ParameterMode.OUT, type = Long.class),
                    @StoredProcedureParameter(name = Pochette.SP_RECPOCH_PARAM_STRSTARTSIM, mode = ParameterMode.IN, type = String.class),
                    @StoredProcedureParameter(name = Pochette.SP_RECPOCH_PARAM_STRLASTSIM, mode = ParameterMode.IN, type = String.class),
                    @StoredProcedureParameter(name = Pochette.SP_RECPOCH_PARAM_NACTELID, mode = ParameterMode.IN, type = Long.class)
            })
    })
請問您有什么主意嗎?

您還需要注冊存儲過程的參數,因此您的代碼應如下所示:

StoredProcedureQuery storedProcedureQuery = getEntityManager().createNamedStoredProcedureQuery("RECPOCH");

storedProcedureQuery.registerStoredProcedureParameter(Pochette.SP_RECPOCH_PARAM_STRSTARTSIM, String.class, ParameterMode.IN);
storedProcedureQuery.setParameter(Pochette.SP_RECPOCH_PARAM_STRSTARTSIM, pochetteCriteria.getDebutNumPochette());

storedProcedureQuery.registerStoredProcedureParameter(Pochette.SP_RECPOCH_PARAM_STRLASTSIM, String.class, ParameterMode.IN);
storedProcedureQuery.setParameter(Pochette.SP_RECPOCH_PARAM_STRLASTSIM, pochetteCriteria.getFinNumPochette());

storedProcedureQuery.registerStoredProcedureParameter(Pochette.SP_RECPOCH_PARAM_NACTELID, Integer.class, ParameterMode.IN);
storedProcedureQuery.setParameter(Pochette.SP_RECPOCH_PARAM_NACTELID, pochetteCriteria.getActelId());

storedProcedureQuery.registerStoredProcedureParameter(Pochette.SP_RECPOCH_PARAM_NRESULT, Integer.class, ParameterMode.OUT);

storedProcedureQuery.execute();

Integer result = (Integer) storedProcedureQuery.getOutputParameterValue(Pochette.SP_RECPOCH_PARAM_NRESULT);

return Long.valueOf(result);

編輯:這對OP的問題沒有幫助,因為使用了createNamedStoredProcedureQuery ,它會自動聲明並注冊參數。 為了完整起見,我將其保留在此處。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM