为什么我在插入BLOB时在ValueOfCopyOfInterpreter中获得NPE?

时间:2012-07-03 19:47:04

标签: oracle nullpointerexception orbeon

要查看问题:

  1. 在Oracle中创建一个表:

    create table ut_table_ut_service_pj (
       PATH VARCHAR(80),
       BINARY BLOB
    );
    
  2. 将以下管道粘贴到XPL沙箱中,您可以在http://localhost:8080/orbeon/sandbox-transformations/xpl/上访问,在您的系统上替换相应的数据库URI,用户名和密码:

    <p:config xmlns:p="http://www.orbeon.com/oxf/pipeline"
              xmlns:oxf="http://www.orbeon.com/oxf/processors"
              xmlns:xforms="http://www.w3.org/2002/xforms"
              xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
              xmlns:sql="http://orbeon.org/oxf/xml/sql"
              xmlns:odt="http://orbeon.org/oxf/xml/datatypes"
              xmlns:xs="http://www.w3.org/2001/XMLSchema"
              xmlns:exist="http://exist.sourceforge.net/NS/exist">
    
        <p:processor name="oxf:url-generator">
            <p:input name="config">
                <config>
                    <url>test.pdf</url>
                    <mode>binary</mode>
                </config>
            </p:input>
            <p:output name="data" id="document"/>
        </p:processor>
    
        <p:processor name="oxf:sql">
            <p:input name="datasource">
                <datasource>
                    <driver-class-name>oracle.jdbc.OracleDriver</driver-class-name>
                    <uri>jdbc:oracle:thin:@//localhost:1522/globaldb</uri>
                    <username>orbeon</username>
                    <password>password</password>
                </datasource>
            </p:input>
            <p:input name="data" href="#document"/>
            <p:input name="config">
                <sql:config>
                    <sql:connection>
                        <sql:execute>
                            <sql:update debug="write">
                                insert into ut_table_ut_service_pj
                                values('test.pdf',
                                <sql:param select="/*"
                                           type="xs:base64Binary" sql-type="blob"/>
                                )
                            </sql:update>
                        </sql:execute>
                    </sql:connection>
                </sql:config>
            </p:input>
        </p:processor>
    
    </p:config>
    
  3. 这会导致以下异常:

    |----------------------------------------------------------------------------------------------------------------------|
    |Exception: java.lang.NullPointerException                                                                             |
    |----------------------------------------------------------------------------------------------------------------------|
    |org.orbeon.oxf.processor.sql.interpreters.ValueOfCo|<init>                        |ValueOfCopyOfInterpreter.java |  48|
    |org.orbeon.oxf.processor.sql.SQLProcessor$Interpret|addAllDefaultElementHandlers  |SQLProcessor.java             | 476|
    |org.orbeon.oxf.processor.sql.interpreters.ConfigInt|start                         |ConfigInterpreter.java        |  32|
    |org.orbeon.oxf.processor.sql.SQLProcessor$Interpret|startElement                  |SQLProcessor.java             | 503|
    |org.orbeon.oxf.processor.sql.SQLProcessor$RootInter|startElement                  |SQLProcessor.java             | 280|
    

    为什么会这样?

1 个答案:

答案 0 :(得分:0)

NPE是bug。截至2012-07-03,这是fixed

  • ValueOfCopyOfInterpreter中,interpreterContext.getCurrentNode()为空。
    • SQLProcessorInterpreterContext是在RootInterpreter
    • 的构造函数中创建的
    • 解释器上下文currentNodes中的第一个节点添加在SQLProcessorInterpreterContext.setInput()中,null通过RootInterpreter调用{。}}。
    • null来自SQLProcessor.execute(),决定配置中的所有XPath表达式(此处只是/*)都可以进行流式传输,因此无需读取文档,没关系。
  • ValueOfCopyOfInterpreter使用该包装器:
    • 评估列表上的string(.)(雾化),包装列表中的每个元素。
    • 评估string(.)
    • 上的Node
  • 在这两种情况下,基于data输入文档创建包装器确实有意义,而不是来自Dom4jUtils.createDocument(),尽管我不确定它会产生什么影响。
  • 修正
    • 但是,由于此时我们必须有一个当前节点,因为我们正在调用XPathUtils.selectObjectValue()传递当前节点,似乎延迟创建包装器直到那一点是有意义的。
    • 仍然将wrapper保留为对象属性,因此我们不会不必要地重新创建包装器。

由于另一个bug,下一个错误是Invalid sql-type attribute: blob。截至2012-07-03,这是fixed

  • 这是由<sql:param select="/*" type="xs:base64Binary" sql-type="blob"/>
  • 触发的
  • QueryInterpreter中,如果类型为xs:anyURI,那么我们对BLOB和CLOB使用相同的技术。
  • 但是如果类型是xs:base64Binary,如果类型是BLOB,我们会通过异常。
    • BTW,这是MySQL和Oracle持久层存储文件时使用的内容。
  • 因此,当类型为xs:base64Binary时,执行相同操作似乎是合理的。