0

我有将数据插入 Oracle 行的 SQL 查询。当我运行该语句时,我得到了 NPE。

public int saveData(int result) throws SQLException, java.text.ParseException, NoSuchAlgorithmException {

    String SqlStatement = null;

    if (ds == null) {
        throw new SQLException();
    }

    Connection conn = ds.getConnection();
    if (conn == null) {
        throw new SQLException();
    }

    PreparedStatement ps = null;

    /*

    CREATE TABLE USERS(
        USERID INTEGER NOT NULL,
        GROUPID INTEGER,
        SPECIALNUMBER VARCHAR2(60 ),
        USERNAME VARCHAR2(50 ),
        PASSWD VARCHAR2(50 ),
        DATETOCHANGEPASSWD DATE,
        ADDRESS VARCHAR2(60 ),
        STATEREGION VARCHAR2(50 ),
        COUNTRY VARCHAR2(50 ),
        USERSTATUS VARCHAR2(30 ),
        TELEPHONE VARCHAR2(50 ),
        DATEUSERADDED DATE,
        USEREXPIREDATE DATE,
        DATEUSERLOCKED CHAR(20 ),
        CITY VARCHAR2(50 ),
        EMAIL VARCHAR2(50 ),
        DESCRIPTION CLOB
    )
   */

    try {
        conn.setAutoCommit(false);
        boolean committed = false;
        try {           
            String getTimeStampTemplateSQL = "(select (select settingvalue from globalsettings where settingname = 'DateFormat') || ' ' ||"
                                             + "(select settingvalue from globalsettings where settingname = 'TimeFormat') from dual)";

            /* insert into Oracle the default system(Linux) time */
            SqlStatement = "INSERT INTO USERS VALUES (?, ?, ?, ?, ?, to_timestamp(?, " 
                    + getTimeStampTemplateSQL + "), ?, ?, ?, ?, ?, SYSTIMESTAMP, to_timestamp(?, " + getTimeStampTemplateSQL +
                    "), ?, ?, ?, ?)";

            ps = conn.prepareStatement(SqlStatement);

            ps.setString(1, formMap.get("USERID"));
            ps.setString(2, formMap.get("GROUPID"));
            ps.setString(3, formMap.get("SPECIALNUMBER"));
            ps.setString(4, formMap.get("USERNAME"));
            ps.setString(5, passwdConvert(formMap.get("PASSWD")));
            ps.setString(6, formMap.get("DATETOCHANGEPASSWD").trim().length() == 0 ? null : formMap.get("DATETOCHANGEPASSWD").trim() + " " + formMap.get("HOURTOCHANGEPASSWD").trim());
            ps.setString(7, formMap.get("ADDRESS"));
            ps.setString(8, formMap.get("STATEREGION"));
            ps.setString(9, formMap.get("COUNTRY"));
            ps.setString(10, formMap.get("USERSTATUS"));

            // If the user set Account Status to Blocked insert SYSTIMESTAMP into DATEUSERLOCKED
            if ((formMap.get("USERSTATUS")!=null) && (formMap.get("USERSTATUS")).equals("Blocked")){
                formMap.put("DATEUSERLOCKED", "SYSTIMESTAMP");
            }               

            ps.setString(11, formMap.get("TELEPHONE"));
            ps.setString(12, formMap.get("USEREXPIREDATE").trim().length() == 0 ? null : formMap.get("USEREXPIREDATE").trim() + " " + formMap.get("USEREXPIREHOUR").trim());

            //ps.setString(13, formMap.get("DATEUSERLOCKED").trim().length() == 0 ? null : formMap.get("DATEUSERLOCKED"));

            ps.setString(13, ((formMap.get("DATEUSERLOCKED")==null) || ((formMap.get("DATEUSERLOCKED")!=null) && (formMap.get("DATEUSERLOCKED").trim().length()==0)))? null : formMap.get("DATEUSERLOCKED"));

            ps.setString(14, formMap.get("CITY"));
            ps.setString(15, formMap.get("EMAIL"));
            ps.setString(16, formMap.get("DESCRIPTION"));


            ps.executeUpdate();

            conn.commit();
            committed = true;
        }
        finally 
        {
            if (!committed) {
                conn.rollback();
            }
        }
    } finally {
        /* Release the resources */
        ps.close();
        conn.close();
    }
    // For JGrown message
    FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null, new FacesMessage("Successful", "User " + formMap.get("USERID") + " is created!"));

    return result;
}

我收到此错误:

javax.faces.FacesException: #{AddAccountController.saveData(1)}: java.sql.SQLDataException: ORA-01858: a non-numeric character was found where a numeric was expected

    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118)
    at javax.faces.component.UICommand.broadcast(UICommand.java:315)
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259)
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
    at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
    at java.lang.Thread.run(Thread.java:722)
Caused by: javax.faces.el.EvaluationException: java.sql.SQLDataException: ORA-01858: a non-numeric character was found where a numeric was expected

    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102)
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
    ... 31 more
Caused by: java.sql.SQLDataException: ORA-01858: a non-numeric character was found where a numeric was expected

    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:445)
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:396)
    at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:879)
    at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:450)
    at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:192)
    at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:531)
    at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:207)
    at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:1044)
    at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1329)
    at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3584)
    at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3665)
    at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(OraclePreparedStatementWrapper.java:1352)
    at com.sun.gjc.spi.base.PreparedStatementWrapper.executeUpdate(PreparedStatementWrapper.java:125)
    at com.DX_57.AC_57.AddAccount.saveData(AddAccount.java:207)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at javax.el.BeanELResolver.invokeMethod(BeanELResolver.java:779)
    at javax.el.BeanELResolver.invoke(BeanELResolver.java:528)
    at javax.el.CompositeELResolver.invoke(CompositeELResolver.java:257)
    at com.sun.el.parser.AstValue.invoke(AstValue.java:248)
    at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:302)
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
    ... 32 more
|#]

你能帮我解决这个问题吗?也许准备好的语句的顺序不正确?

PS问题出在这里:

ps.setString(13, formMap.get("DATEUSERLOCKED").trim().length() == 0 ? null : formMap.get("DATEUSERLOCKED"));
4

4 回答 4

2

异常被抛出

AddAccount.java:221

如果你不能直接弄清楚这一行是做什么的(如果你能从这个文件中发布这段代码片段会很好)那么调试程序应该是你发现错误的第一步(这 - 实际上 - 是一个一般规则)。

对您发布的代码的一般评论(这也可能是问题的根本原因)。每当你这样做时,formMap.get("<key>")你都不能确定formMap会为此返回一个not-null对象<key>。您只是将此映射返回的值直接分配给准备好的语句的情况可能没有问题,但是当您级联调用该返回对象的其他方法时(例如,如果对象是,equalstrim可能导致NPE iffnull)。

所以考虑改变调用,如:

if ((formMap.get("USERSTATUS")).equals("Blocked")){
...
}

类似于:

if ((formMap.get("USERSTATUS")!=null) && (formMap.get("USERSTATUS")).equals("Blocked")){
...
}

或者

if ("Blocked".equals(formMap.get("USERSTATUS"))){
...
}

在你打电话的地方trimlength地图上的结果项目上

编辑

使用三元运算符 ( ?:) 进行检查的情况稍微复杂一些null:如果项目的长度为 0,则需要分配 null,因此这分解为以下逻辑:

如果从 formMap 返回的对象是 null 或者(如果从 formMap 返回的对象不是 NULL 并且它的长度为零)返回 NULL 否则返回对象本身

因此,这导致以下检查:

((formMap.get("DATEUSERLOCKED")==null) || ((formMap.get("DATEUSERLOCKED")!=null) && (formMap.get("DATEUSERLOCKED").trim().length()==0)))? null : formMap.get("DATEUSERLOCKED"));
于 2012-08-10T10:05:35.793 回答
2

(作为一般规则),您可以重写以下行以更安全:

if ((formMap.get("USERSTATUS")).equals("Blocked")) {

假设 ,formMap != null最好写成:

if ("Blocked".equals(formMap.get("USERSTATUS"))) {

在这种情况下,即使 formMap 不包含 key 也是安全的USERSTATUS

于 2012-08-10T09:15:08.157 回答
1

我能看到 NPE 的唯一机会是当你这样做时

formMap.get(...).trim().length() ...
passwdConvert(formMap.get("PASSWD"))

您是否尝试过调试?

我在我的项目中应用的一般规则是:每行一个语句 - 这样 StackTraces 中的 line-nubers 会更有帮助。

于 2012-08-10T09:19:23.617 回答
1

尝试null像这样添加:

ps.setString(13, formMap.get("DATEUSERLOCKED").trim().length() == 0 ? 'null' : formMap.get("DATEUSERLOCKED"));
于 2012-08-10T11:25:14.077 回答