0

簡単なクエリがあります

select t.firstname, t.lastname, t.zipcode, t.city 
from name_data t where name_id = ?

'?' は入力パラメータであり、nullになることはありません。

クエリは、次のいずれかのようなレコードを返します。

ケース1-個人

 'First Name'   'Last Name'     'zipcode'   'city'
 -------------------------------------------------------
 John           Doe             1177        Somewhere

ケース2-会社

 'First Name'   'Last Name'     'zipcode'   'city'
 -----------------------------------------------------------
 <<null>>       ACME Ltd        1199        'Somewhere else'

2番目のレコードを取得すると、DSSはNullPointerExceptionをスローします。

これは、Firstnameの<>値と、SQL(Oracle)でnull値をテストすることでこれを回避する方法を見つけたためだと思います。

"select nvl(t.firstname、'')firstname、nvl(t.lastname、'')、lastname、nvl(t.zipcode、'')、nvl(t.city、'')etc ..."

そして、これはオプションであるため、nullになる可能性のあるすべての列(私のクエリはこれより少し長い)です。

データベースが正しく設計されていれば(理論的には)これは起こらないはずですが(人と会社を管理するための2つの異なるエンティティを作成するなど)、それは商用製品であり、変更することはできず、代わりに簡単なケースで説明しました長いクエリ。

私の.dbsの抜粋は次のとおりです。

<?xml version="1.0" encoding="UTF-8"?>
<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:noNamespaceSchemaLocation="http:///org/wso2/carbonstudio/eclipse/ds" 
    name="${groupId}.${artifactId}-customeraddress-1" 
    serviceNamespace="urn:customeraddress.database.mycompany.org/1" 
    serviceGroup="${groupId}" baseURI="">
  <description>This is the datasource to access the customer address information</description>
  <config id="ambocs">
    <property name="org.wso2.ws.dataservice.driver">@ambocs.driver@</property>
    <property name="org.wso2.ws.dataservice.protocol">@ambocs.url@</property>
    <property name="org.wso2.ws.dataservice.user">@ambocs.user@</property>
    <property name="org.wso2.ws.dataservice.password">@ambocs.password@</property>
    <property name="org.wso2.ws.dataservice.minpoolsize">@ambocs.minpoolsize@</property>
    <property name="org.wso2.ws.dataservice.maxpoolsize">@ambocs.maxpoolsize@</property>
    <property name="org.wso2.ws.dataservice.validation_query">select 1 from dual</property>
  </config>
  <query id="getCustomerAddressByIdRef" useConfig="ambocs" returnRowId="true">
    <sql>
        select 
            nvl(nd.first_name, ' ') first_name, 
            nvl(nd.last_name, ' ') last_name,
            nvl(nd.adr_zip, ' ') zipcode,
            nvl(nd.adr_city, ' ') city, 
            nvl(nd.adr_country, ' ') country 
        from name_data nd
        where nd.name_id = ?
    </sql>
    <properties>
      <property name="org.wso2.ws.dataservice.query_timeout"></property>
      <property name="org.wso2.ws.dataservice.fetch_direction"></property>
      <property name="org.wso2.ws.dataservice.fetch_size"></property>
      <property name="org.wso2.ws.dataservice.max_field_size"></property>
      <property name="org.wso2.ws.dataservice.max_rows"></property>
    </properties>
    <result element="ContactDetails" rowName="ContactDetail" 
       defaultNamespace="urn:customeraddress.database.mycompany.org/1" outputType="xml">
      <attribute name="firstName" column="first_name" query-param="" requiredRoles="" xsdType="xs:string"/>
      <attribute name="lastName" column="last_business_name" query-param="" requiredRoles="" xsdType="xs:string"/>
      <attribute name="locality" column="city" query-param="" requiredRoles="" xsdType="xs:string"/>
      <attribute name="postcode" column="zipcode" query-param="" requiredRoles="" xsdType="xs:string"/>
      <attribute name="country" column="country" query-param="" requiredRoles="" xsdType="xs:string"/>      
    </result>
    <param name="nameId" type="IN" sqlType="STRING" defaultValue="" />
  </query>
  <operation name="getCustomerAddressById">
    <call-query href="getCustomerAddressByIdRef">
        <with-param name="nameId" column="nameId" query-param="nameId"/>
    </call-query>
  </operation>
</data>

クエリによって返されるnull値を管理するために.dbsを挿入するオプションがあるかどうか知っていますか?

wso2.orgでドキュメントを見つけようとしましたが、これは非常に単純な例であり、このケースについては何もありません。

UPDATE ここでテーブルスキーマ:

CREATE TABLE "NAME_DATA"
(
    "NAME_ID"               NUMBER(9,0) CONSTRAINT "PK_NAME_ID" NOT NULL ENABLE,
    "SYS_CREATION_DATE"     DATE NOT NULL ENABLE,
    "SYS_UPDATE_DATE"       DATE,
    "LAST_NAME"             VARCHAR2(60),
    "FIRST_NAME"            VARCHAR2(32),
    "ZIP_CODE"              VARCHAR2(4),
    "CITY"                  VARCHAR2(255),
    "COUNTRY"               CHAR(3 BYTE),
    CONSTRAINT "NAME_DATA_PK" PRIMARY KEY ("NAME_ID")
) 

CREATE UNIQUE INDEX "NAME_DATA_PK" ON "NAME_DATA" ("NAME_ID")
CREATE INDEX "IDX_NAME_DATA_1" ON "NAME_DATA"("LAST_NAME","FIRST_NAME")
CREATE INDEX "IDX_NAME_DATA_2" ON "NAME_DATA"(UPPER("FIRST_NAME"))
CREATE INDEX "IDX_NAME_DATA_3" ON "NAME_DATA"(UPPER("LAST_NAME"))

更新2-スタックトレース:

TID: [0] [WSO2 Data Services Server] [2012-03-27 14:02:22,730] ERROR {org.apache.axis2.transport.http.AxisServlet} -   {org.apache.axis2.transport.http.AxisServlet}
java.lang.NullPointerException
    at com.ctc.wstx.sw.BaseNsStreamWriter.doWriteAttr(BaseNsStreamWriter.java:468)
    at com.ctc.wstx.sw.BaseNsStreamWriter.writeAttribute(BaseNsStreamWriter.java:230)
    at org.apache.axiom.util.stax.wrapper.XMLStreamWriterWrapper.writeAttribute(XMLStreamWriterWrapper.java:88)
    at org.apache.axiom.om.impl.MTOMXMLStreamWriter.writeAttribute(MTOMXMLStreamWriter.java:230)
    at org.wso2.carbon.dataservices.core.engine.DSWrappedXMLStreamWriter.writeXMLEvent(DSWrappedXMLStreamWriter.java:418)
    at org.wso2.carbon.dataservices.core.engine.DSWrappedXMLStreamWriter.writeOutInitialXMLEvents(DSWrappedXMLStreamWriter.java:508)
    at org.wso2.carbon.dataservices.core.engine.DSWrappedXMLStreamWriter.finalizeBuffering(DSWrappedXMLStreamWriter.java:501)
    at org.wso2.carbon.dataservices.core.engine.DSWrappedXMLStreamWriter.flush(DSWrappedXMLStreamWriter.java:145)
    at org.wso2.carbon.dataservices.core.engine.DSOMDataSource.execute(DSOMDataSource.java:102)
    at org.wso2.carbon.dataservices.core.engine.DSOMDataSource.serialize(DSOMDataSource.java:110)
    at org.apache.axiom.om.impl.llom.OMSourcedElementImpl.internalSerialize(OMSourcedElementImpl.java:691)
    at org.apache.axiom.om.impl.util.OMSerializerUtil.serializeChildren(OMSerializerUtil.java:563)
    at org.apache.axiom.om.impl.llom.OMElementImpl.internalSerialize(OMElementImpl.java:875)
    at org.apache.axiom.soap.impl.llom.SOAPEnvelopeImpl.serializeInternally(SOAPEnvelopeImpl.java:283)
    at org.apache.axiom.soap.impl.llom.SOAPEnvelopeImpl.internalSerialize(SOAPEnvelopeImpl.java:245)
    at org.apache.axiom.om.impl.llom.OMSerializableImpl.serializeAndConsume(OMSerializableImpl.java:193)
    at org.apache.axis2.transport.http.SOAPMessageFormatter.writeTo(SOAPMessageFormatter.java:74)
    at org.apache.axis2.transport.http.CommonsHTTPTransportSender.sendUsingOutputStream(CommonsHTTPTransportSender.java:409)
    at org.apache.axis2.transport.http.CommonsHTTPTransportSender.invoke(CommonsHTTPTransportSender.java:286)
    at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:443)
    at org.apache.axis2.receivers.AbstractInOutSyncMessageReceiver.invokeBusinessLogic(AbstractInOutSyncMessageReceiver.java:45)
    at org.apache.axis2.receivers.AbstractMessageReceiver.receive(AbstractMessageReceiver.java:110)
    at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:181)
    at org.apache.axis2.transport.http.HTTPTransportUtils.processHTTPPostRequest(HTTPTransportUtils.java:172)
    at org.apache.axis2.transport.http.AxisServlet.doPost(AxisServlet.java:146)
    at org.wso2.carbon.core.transports.CarbonServlet.doPost(CarbonServlet.java:199)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.eclipse.equinox.http.servlet.internal.ServletRegistration.handleRequest(ServletRegistration.java:90)
    at org.eclipse.equinox.http.servlet.internal.ProxyServlet.processAlias(ProxyServlet.java:111)
    at org.eclipse.equinox.http.servlet.internal.ProxyServlet.service(ProxyServlet.java:67)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.wso2.carbon.bridge.BridgeServlet.service(BridgeServlet.java:164)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.wso2.carbon.server.CarbonStuckThreadDetectionValve.invoke(CarbonStuckThreadDetectionValve.java:154)
    at org.wso2.carbon.server.TomcatServer$1.invoke(TomcatServer.java:254)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:563)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:399)
    at org.apache.coyote.http11.Http11NioProcessor.process(Http11NioProcessor.java:396)
    at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:356)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1534)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)
TID: [0] [WSO2 Data Services Server] [2012-03-27 14:02:22,730] ERROR {org.apache.axis2.transport.http.AxisServlet} -   {org.apache.axis2.transport.http.AxisServlet}
java.lang.NullPointerException
    at com.ctc.wstx.sw.BaseNsStreamWriter.doWriteAttr(BaseNsStreamWriter.java:468)
    at com.ctc.wstx.sw.BaseNsStreamWriter.writeAttribute(BaseNsStreamWriter.java:230)
    at org.apache.axiom.util.stax.wrapper.XMLStreamWriterWrapper.writeAttribute(XMLStreamWriterWrapper.java:88)
    at org.apache.axiom.om.impl.MTOMXMLStreamWriter.writeAttribute(MTOMXMLStreamWriter.java:230)
    at org.wso2.carbon.dataservices.core.engine.DSWrappedXMLStreamWriter.writeXMLEvent(DSWrappedXMLStreamWriter.java:418)
    at org.wso2.carbon.dataservices.core.engine.DSWrappedXMLStreamWriter.writeOutInitialXMLEvents(DSWrappedXMLStreamWriter.java:508)
    at org.wso2.carbon.dataservices.core.engine.DSWrappedXMLStreamWriter.finalizeBuffering(DSWrappedXMLStreamWriter.java:501)
    at org.wso2.carbon.dataservices.core.engine.DSWrappedXMLStreamWriter.flush(DSWrappedXMLStreamWriter.java:145)
    at org.wso2.carbon.dataservices.core.engine.DSOMDataSource.execute(DSOMDataSource.java:102)
    at org.wso2.carbon.dataservices.core.engine.DSOMDataSource.serialize(DSOMDataSource.java:110)
    at org.apache.axiom.om.impl.llom.OMSourcedElementImpl.internalSerialize(OMSourcedElementImpl.java:691)
    at org.apache.axiom.om.impl.util.OMSerializerUtil.serializeChildren(OMSerializerUtil.java:563)
    at org.apache.axiom.om.impl.llom.OMElementImpl.internalSerialize(OMElementImpl.java:875)
    at org.apache.axiom.soap.impl.llom.SOAPEnvelopeImpl.serializeInternally(SOAPEnvelopeImpl.java:283)
    at org.apache.axiom.soap.impl.llom.SOAPEnvelopeImpl.internalSerialize(SOAPEnvelopeImpl.java:245)
    at org.apache.axiom.om.impl.llom.OMSerializableImpl.serializeAndConsume(OMSerializableImpl.java:193)
    at org.apache.axis2.transport.http.SOAPMessageFormatter.writeTo(SOAPMessageFormatter.java:74)
    at org.apache.axis2.transport.http.CommonsHTTPTransportSender.sendUsingOutputStream(CommonsHTTPTransportSender.java:409)
    at org.apache.axis2.transport.http.CommonsHTTPTransportSender.invoke(CommonsHTTPTransportSender.java:286)
    at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:443)
    at org.apache.axis2.receivers.AbstractInOutSyncMessageReceiver.invokeBusinessLogic(AbstractInOutSyncMessageReceiver.java:45)
    at org.apache.axis2.receivers.AbstractMessageReceiver.receive(AbstractMessageReceiver.java:110)
    at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:181)
    at org.apache.axis2.transport.http.HTTPTransportUtils.processHTTPPostRequest(HTTPTransportUtils.java:172)
    at org.apache.axis2.transport.http.AxisServlet.doPost(AxisServlet.java:146)
    at org.wso2.carbon.core.transports.CarbonServlet.doPost(CarbonServlet.java:199)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.eclipse.equinox.http.servlet.internal.ServletRegistration.handleRequest(ServletRegistration.java:90)
    at org.eclipse.equinox.http.servlet.internal.ProxyServlet.processAlias(ProxyServlet.java:111)
    at org.eclipse.equinox.http.servlet.internal.ProxyServlet.service(ProxyServlet.java:67)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.wso2.carbon.bridge.BridgeServlet.service(BridgeServlet.java:164)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.wso2.carbon.server.CarbonStuckThreadDetectionValve.invoke(CarbonStuckThreadDetectionValve.java:154)
    at org.wso2.carbon.server.TomcatServer$1.invoke(TomcatServer.java:254)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:563)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:399)
    at org.apache.coyote.http11.Http11NioProcessor.process(Http11NioProcessor.java:396)
    at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:356)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1534)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)

これをテストするには、DBS内のすべての「nvl(...)」を削除する必要があります。そうしないと、正常に機能します。これは、first_nameが「null」であるレコードでした。

4

2 に答える 2

2

この問題は、結果セットで「属性」タイプの出力マッピングを使用する場合に発生します。これがそのために作成されたJiraです

回避策として、属性としてではなく要素として列を使用でき、null値を適切に処理できます。

つまり、上記のdbsファイルで、次のように結果セットを使用します。

<result element="ContactDetails" rowName="ContactDetail" 
   defaultNamespace="urn:customeraddress.database.mycompany.org/1" outputType="xml">
  <element name="firstName" column="first_name" query-param="" requiredRoles="" xsdType="xs:string"/>
  <element name="lastName" column="last_business_name" query-param="" requiredRoles="" xsdType="xs:string"/>
  <element name="locality" column="city" query-param="" requiredRoles="" xsdType="xs:string"/>
  <element name="postcode" column="zipcode" query-param="" requiredRoles="" xsdType="xs:string"/>
  <element name="country" column="country" query-param="" requiredRoles="" xsdType="xs:string"/>      
</result>
于 2012-05-05T08:45:12.567 に答える
0

使用しているデータサービスのバージョンについて教えてください。これは、最新のパック(wso2dataservices-2.6.3)で正常に機能します。データベーステーブルに「null」値がある場合、dssを介して取得した結果に「xsi:nil="true"」と表示されます。

次の結果は、最後の結果セットのテーブルにnull値が含まれている場合の例を示しています。

<Entries xmlns="http://ws.wso2.org/dataservice">
   <Entry>
      <EMPLOYEENUMBER>1</EMPLOYEENUMBER>
      <LASTNAME>dinusha</LASTNAME>
   </Entry>
   <Entry>
      <EMPLOYEENUMBER **xsi:nil="true"** xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
      <LASTNAME **xsi:nil="true**" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
   </Entry>
</Entries> 
于 2012-03-22T07:25:49.563 に答える