【发布时间】: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