2012-03-19 66 views
0

我有一个简单的查询如何WSO2DSS管理查询XML映射其中包含空值某些列

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

的“?”是输入参数,并且不会为空。

查询返回看上去就像其中的一个纪录:

案例1 - 个人

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

案例2 - 公司

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

当我收到第二战绩, DSS抛出一个NullPointerException。

我想这是因为<>的名字和值,我发现了一种通过在SQL(Oracle)的测试null值

绕过这个“选择NVL(t.firstname,'“)姓,nvl(t.lastname,''),lastname,nvl(t.zipcode,''),nvl(t.city,'')等等......“

而且这对于所有可以为null的列(我的查询比这长一点),因为它们是单项选择。

我知道这不应该发生(理论上)如果数据库设计正确(就像创建两个不同的实体来管理人员和公司) 但它是一个商业产品,然后我只是不能改变它,我拿了一个简单的例子来解释一个长的查询。

我.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">@[email protected]</property> 
    <property name="org.wso2.ws.dataservice.protocol">@[email protected]</property> 
    <property name="org.wso2.ws.dataservice.user">@[email protected]</property> 
    <property name="org.wso2.ws.dataservice.password">@[email protected]</property> 
    <property name="org.wso2.ws.dataservice.minpoolsize">@[email protected]</property> 
    <property name="org.wso2.ws.dataservice.maxpoolsize">@[email protected]</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> 

你知道,如果有就摆在.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) 

为了测试这一点,你必须删除所有“NVL(...) “在DBS中,否则它运作良好。这是first_name为“null”的记录。

回答

2

当您在结果集中使用“属性”类型输出映射时,会发生此问题。 Here is the Jira created for it

作为一种解决方法,您可以使用列作为元素而不是属性,它可以正确处理空值。

即在上面提供的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> 
+0

通过使用元素替代属性可以很好地工作。最后,我可以像生成属性一样管理生成的对象(结果)。感谢您的支持。 – 2012-05-09 09:43:00

0

你能提一下你使用的数据服务版本吗?这在最新的包(wso2dataservices-2.6.3)中工作正常。如果你在数据库表中有'空'值,那么它会在你通过dss检索到的结果中显示为“xsi:nil =”true“”。

以下结果向您显示了一个示例,其中最后一个结果集在表中包含空值。

<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> 
+0

是的我期待在结果XML中有nil = true,但它不能在我的平台上工作。我也使用DSS 2.6.3。 – 2012-03-22 09:22:51