【问题标题】:JPA and ORACLE function: error when call a stored procedure using NamedNativeQueryJPA 和 ORACLE 函数:使用 NamedNativeQuery 调用存储过程时出错
【发布时间】:2015-12-23 01:00:12
【问题描述】:

我有一个 Oracle 函数

CREATE OR REPLACE FUNCTION SOL.UPDATE_LD_OAUDITORID (
vCUSTOMERID       NUMBER,
vAPPOINTOFCAID    NUMBER,
vAUDITORID        NUMBER,
vOAUDITORID       NUMBER)

RETURN NUMBER
IS
PRAGMA AUTONOMOUS_TRANSACTION;

vGROUPID      NUMBER;
rTN           NUMBER;

CURSOR c
IS
  SELECT COMPANYID,
         GROUPID,
         PERIODID,
         PROCESSID,
         CUSTOMERID,
         APPOINTOFCAID,
         AUDITORID
    FROM LIQUIDATIONSDETAILS
   WHERE     CUSTOMERID = vCUSTOMERID
         AND APPOINTOFCAID = vAPPOINTOFCAID
         AND AUDITORID = vAUDITORID
         AND (       PERIODID = fn_periodcurrent
                 AND PROCESSID = FN_PROCESSCURRENT
              OR PERIODID = fn_periodNEXT AND PROCESSID = FN_PROCESSNEXT) FOR UPDATE;

TYPE nt_type IS TABLE OF c%ROWTYPE;
l_arr         nt_type;
DML_ERRORS    EXCEPTION;
PRAGMA EXCEPTION_INIT (DML_ERRORS, -24381);
l_errors      NUMBER;
errorCnt      NUMBER;
errString     VARCHAR2 (4000);
l_idx         NUMBER;
BEGIN
SELECT FN_CURRENTGROUP (vOAUDITORID) INTO vGROUPID FROM DUAL;

OPEN c;

LOOP
  FETCH c
  BULK COLLECT INTO l_arr
  LIMIT 500;

  EXIT WHEN l_arr.COUNT = 0;

  BEGIN
     FORALL i IN 1 .. l_arr.COUNT SAVE EXCEPTIONS
        UPDATE liquidationsdetails
           SET groupid = vgroupid, auditorid = vOAUDITORID
         WHERE     COMPANYID = l_arr (i).COMPANYID
               AND GROUPID = l_arr (i).GROUPID
               AND PERIODID = l_arr (i).PERIODID
               AND PROCESSID = l_arr (i).PROCESSID
               AND CUSTOMERID = l_arr (i).CUSTOMERID
               AND APPOINTOFCAID = l_arr (i).APPOINTOFCAID
               AND AUDITORID = l_arr (i).AUDITORID;

     RTN := 1;
  EXCEPTION
     WHEN dml_errors
     THEN                        -- Now we figure out what failed and why.
        errorCnt := SQL%BULK_EXCEPTIONS.COUNT;
        errString :=
           'Number of statements that failed: ' || TO_CHAR (errorCnt);

        RTN := 0;
  END;
END LOOP;

CLOSE C;

COMMIT;

RETURN RTN;
END;
/

一个带有namednativequery函数调用的虚拟实体bean

@Entity
@NamedNativeQueries({
@javax.persistence.NamedNativeQuery(name = "updateldoauditorid", query = ""
        + "{? =  call UPDATE_LD_OAUDITORID(:customerid, :appointofcaid, :auditorid, :oauditorid)}", resultClass = DummyEntity.class,
        hints = {
            @javax.persistence.QueryHint(name = "org.hibernate.callable", value = "true")})})

public class DummyEntity implements Serializable {
...

无状态会话

@Override
public int spUpdate_ld_oauditorid(String customerid, String appointofcaid, String auditorid, String oauditorid) {
    Integer isup = (Integer) em.createNamedQuery("updateldoauditorid")
            .setParameter(customerid, customerid)
            .setParameter(appointofcaid, appointofcaid)
            .setParameter(auditorid, auditorid)
            .setParameter(oauditorid, oauditorid)
            .getSingleResult();

    return isup;
}

一个调用下面的jsp页面

try {
        update = dummyFacade.spUpdate_ld_oauditorid(customerid, appointofcaid, auditorid, oauditorid);

    } catch (Exception ex) {
        ex.printStackTrace();
    }

我收到了错误

java.lang.NullPointerException 在 org.apache.jsp.members.appointsofcas.liquidations.liquidations_005fa_005foauditorid_jsp.Updateldoauditorid(liquidations_005fa_005foauditorid_jsp.java:96) org.apache.jsp.members.apppointsofcas.liquidations.liquidations_005fa_005foauditorid_jsp._jspService(liquidations_005fa_005foauditorid_jsp.java:415) 执行jsp页面时

【问题讨论】:

  • 可能不是你的问题。但是执行 DML 的函数是个坏主意——您需要为此使用过程。并且将自治事务用于写入持久日志之外的任何事情都是一个等待发生的错误。
  • Justin Cave 你有什么推荐的?
  • 将其更改为存储过程。摆脱自治事务。我也会摆脱提交——让应用程序处理事务管理。您的错误管理看起来也令人难以置信——您真的只想返回一个字符串,告诉您在最后一批最多 500 行中发生了多少失败?没有指示哪些行失败或可能遇到了数千个其他错误?或者错误是什么?
  • Justin Cave 可以举个例子吗?例如,我可以用过程(功能)做什么?算了吧?我的错误管理是从一个例子中复制而来的。此功能最多更新 2 条记录。如果出现异常,我只需要返回应用程序..

标签: java oracle jsp jpa stored-procedures


【解决方案1】:

在您的无状态会话 bean 中,您错误地设置了参数。您使用了两次参数的值,当您调用setParameter() 时,您可能忘记了第一个参数的""

@Override
public int spUpdate_ld_oauditorid(String customerid, String appointofcaid, String auditorid, String oauditorid) {
    Integer isup = (Integer) em.createNamedQuery("updateldoauditorid")
        .setParameter("customerid", customerid)
        .setParameter("appointofcaid", appointofcaid)
        .setParameter("auditorid", auditorid)
        .setParameter("oauditorid", oauditorid)
        .getSingleResult();

return isup;
}

【讨论】:

  • 好的,大卫,我更改了代码,但出现了另一个错误在调用 EJB DummyFacade 期间发生系统异常 ... at com.sun.proxy.$Proxy283.spUpdate_ld_oauditorid(Unknown Source)跨度>
  • 为查询设置参数是代码中的问题之一。如果没有完整的错误堆栈跟踪,现在很难说您的问题是什么。
  • 如何添加完整的 StackTrace?
  • 调用 EJB DummyFacade 时发生系统异常,方法:public int sol.session.DummyFacade.spUpdate_ld_oauditorid(java.lang.String,java.lang.String,java.lang.String,java .lang.String)|#]
  • 引起:java.lang.IllegalArgumentException:NamedQuery of name: updateldoauditorid not found.
猜你喜欢
  • 2015-11-20
  • 2018-10-04
  • 2014-08-16
  • 1970-01-01
  • 2020-07-08
  • 2015-05-20
  • 2011-12-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多