Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    XPath mapping in abstract classes not working

    Please help me with a DMI issue. This is best to explain by example. I am getting the following exception in my log:

    Code:
    com.isomorphic.util.JXPathContextObjectFactory - Provided XPath has one or more null objects, attempt to create missing object failed. JXPathContext bean: net.cnsonline.air.model.view.FlightVO@19b2ca1, parent object: net.cnsonline.air.model.view.FlightVO@19b2ca1, property that creation failed: carrier, property index (in case of collection or array): 0
    java.lang.Exception: Cannot instantiate interface.
    	at com.isomorphic.util.JXPathContextObjectFactory.createObject(JXPathContextObjectFactory.java:235)
    	at org.apache.commons.jxpath.ri.model.beans.PropertyPointer.createPath(PropertyPointer.java:171)
    	at org.apache.commons.jxpath.ri.model.beans.BeanPropertyPointer.createPath(BeanPropertyPointer.java:238)
    	at org.apache.commons.jxpath.ri.JXPathContextReferenceImpl.createPath(JXPathContextReferenceImpl.java:523)
    	at org.apache.commons.jxpath.ri.JXPathContextReferenceImpl.createPath(JXPathContextReferenceImpl.java:497)
    	at com.isomorphic.datasource.DataSource.setProperties(DataSource.java:1744)
    	at com.isomorphic.base.Reflection.adaptValue(Reflection.java:1526)
    	at com.isomorphic.base.Reflection.adaptArgsAndInvoke(Reflection.java:899)
    	at com.isomorphic.datasource.DataSourceDMI.execute(DataSourceDMI.java:416)
    	at com.isomorphic.datasource.DataSourceDMI.execute(DataSourceDMI.java:64)
    	at com.isomorphic.datasource.DSRequest.execute(DSRequest.java:2366)
    	at com.isomorphic.servlet.IDACall.handleDSRequest(IDACall.java:215)
    	at com.isomorphic.servlet.IDACall.processRPCTransaction(IDACall.java:172)
    	at com.isomorphic.servlet.IDACall.processRequest(IDACall.java:137)
    	at com.isomorphic.servlet.IDACall.doPost(IDACall.java:73)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
    	at com.isomorphic.servlet.BaseServlet.service(BaseServlet.java:152)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
    	at org.apache.catalina.core.StandardContextValve.__invoke(StandardContextValve.java:123)
    	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java)
    	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    	at org.apache.catalina.core.StandardHostValve.__invoke(StandardHostValve.java:168)
    	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java)
    	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
    	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
    	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1001)
    	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
    	at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1770)
    	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)
    Snip from .ds.xml:

    Code:
    <field name="site" type="text" length="50" required="false" valueXPath="site/id" />
    valueXPath="site/id" mapping works when beans are declared like this:

    Code:
    @XmlRootElement(name="flight")
    public class FlightVO {
    
           private AirsiteVO site;
    
           public AirsiteVO getSite() {
                  return site;
           }
    
           public void setSite(AirsiteVO site) {
                  this.site = site;
           }
    }
    BUT not like this using an abstract class, why? Is this a bug?


    Code:
    @XmlRootElement(name="flight")
    public class FlightVO extends AbstractConveyanceVO<AirsiteVO> {
    }
    
    public abstract class AbstractConveyanceVO<S extends AbstractSiteVO> {
    
           protected S site;
    
           public S getSite() {
                  return site;
           }
    
           public void setSite(S site) {
                  this.site = site;
           }
    }
    Thank you in advance

    #2
    If we're trying to apply a value via an XPath, but the Java type is abstract, we don't know what concrete type to use. See DataSourceField.javaClass for how to provide a concrete type.

    Comment


      #3
      Hello.

      Thanks for your response and I have looked in to further the javaClass parameter which I understand but I still cannot get any further. The exception has gone, however, my VO class still does not correctly get mapped when it hits the DMI method. Only the fields which are defined in the VO class gets mapped.

      This is what I have so far (snips):

      Code:
      <operationBindings>
      	        <binding operationType="update" serverMethod="update">
      	        	<serverObject lookupStyle="spring" bean="flightController"/>
      	        </binding>
      	    </operationBindings>
      
      <fields>
      		<field name="id" type="sequence" primaryKey="true" hidden="true"/>
      		<field name="number" type="text" length="128" required="false"/>
      		<field name="site" length="50" required="false" javaClass="net.cnsonline.air.model.view.AirsiteVO" />
      		<field name="status" type="text" length="50" required="false"/>
      		<field name="carrier" type="text" length="30" required="false" javaClass="net.cnsonline.air.model.view.AirlineVO" />
      		<field name="date" title="Flight Date" type="date" length="20" required="false"/>
      		<field name="time" title="Departure Time"  type="text" length="128" required="false"/>
      		<field name="departureLocation" title="AOO" type="text" length="3" javaClass="net.cnsonline.air.model.view.AirportVO" required="false"/>
      		<field name="arrivalLocation" title="AOD" type="text" length="3" javaClass="net.cnsonline.air.model.view.AirportVO" required="false"/>
      	</fields>
      Code:
      public DSResponse update(DSRequest dsRequest, FlightVO flightVO) throws Exception {
      
      etc etc etc
      Code:
      public class FlightVO extends AbstractConveyanceVO<AirsiteVO, AirportVO, AirportVO, 
      AirlineVO> {
      
      	private String number;
      	private String date;
      	private String time;
      
      	public String getNumber() {
      		return number;
      	}
      At runtime the FlightVO correctly has number, date, time etc mapped. But everything else remains null.

      Here is the trace from fiddler:

      Code:
      <transaction xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance" xsi:type="xsd:Object">
      	<transactionNum xsi:type="xsd:long">13</transactionNum>
      	<operations xsi:type="xsd:List">
      		<elem xsi:type="xsd:Object">
      			<criteria xsi:type="xsd:Object">
      				<id xsi:type="xsd:long">98310</id>
      			</criteria>
      			<values xsi:type="xsd:Object">
      				<site xsi:type="xsd:Object">
      					<id>CBA1</id>
      				</site>
      				<id xsi:type="xsd:long">98310</id>
      				<time>12:00</time>
      				<status>ARRIVED</status>
      				<carrier xsi:type="xsd:Object">
      					<id>BA</id>
      				</carrier>
      				<number>2016</number>
      				<departureLocation xsi:type="xsd:Object">
      					<id>LHR</id>
      				</departureLocation>
      				<date xsi:type="xsd:date">0014-01-03</date>
      				<arrivalLocation xsi:type="xsd:Object">
      					<id>EZE</id>
      				</arrivalLocation>
      			</values>
      			<operationConfig xsi:type="xsd:Object">
      				<dataSource>flightOperationsDMI</dataSource>
      				<operationType>update</operationType>
      			</operationConfig>
      			<appID>builtinApplication</appID>
      			<operation>flightOperationsDMI_update</operation>
      			<oldValues xsi:type="xsd:Object">
      				<site xsi:type="xsd:Object">
      					<id>CBA1</id>
      					<customsShedCode xsi:nil="true"/>
      					<airport xsi:nil="true"/>
      					<shedOp xsi:nil="true"/>
      					<name>BA EXPRESS (HEATHROW SOUTH)</name>
      					<community>LAP COURIERS</community>
      					<type xsi:nil="true"/>
      					<customs xsi:nil="true"/>
      					<live xsi:nil="true"/>
      					<country xsi:nil="true"/>
      				</site>
      				<id xsi:type="xsd:long">98310</id>
      				<time>12:00</time>
      				<status>ARRIVED</status>
      				<carrier xsi:type="xsd:Object">
      					<id>BA</id>
      					<name xsi:nil="true"/>
      					<country xsi:nil="true"/>
      				</carrier>
      				<number>2016</number>
      				<departureLocation xsi:type="xsd:Object">
      					<id>LHR</id>
      					<name xsi:nil="true"/>
      					<country xsi:nil="true"/>
      				</departureLocation>
      				<date xsi:type="xsd:date">0014-01-03</date>
      				<arrivalLocation xsi:type="xsd:Object">
      					<id>EZE</id>
      					<name xsi:nil="true"/>
      					<country xsi:nil="true"/>
      				</arrivalLocation>
      			</oldValues>
      		</elem>
      	</operations>
      </transaction>
      Thank you again for your help. Appreciate your time.

      Steven

      Comment


        #4
        We don't follow. If those are the only properties in the bean that you are trying to populate, what are you expecting to happen to the values for DataSourceFields where you have no bean properties?

        Comment


          #5
          FlightVO extends AirsiteVO etc. So even though FlightVO has three of its own properties the AirsiteVO containers members of its own:

          Code:
          public class AirsiteVO extends AbstractLocationVO {
          
          	private AirportVO airport;
          	private String community;
          	private SiteTypeVO siteType;
          	private Boolean live;
          	private String shedOp;
          	private String customs;
          	private String customsShedCode;
          So effectively why is SmartClient treating FlightVO differently just because it extends AirsiteVO?

          An example. Why is it we get the correct mapping when our FlightVO looks like this:

          Code:
          public class FlightVO {
          
          	private String number;
          	private String date;
          	private String time;
          	private String community;
          	private String shedOp;
          	private String customs;
          	private String customsShedCode;
          The above works perfectly but as soon as we extend with another class the mapping does not take place and these values are null.

          Just for clarification here is the start of AbstractConveyanceVO which FlightVO so you can see the full shape of the objects.

          Code:
          public abstract class AbstractConveyanceVO<S extends AbstractLocationVO, 
          D extends AbstractLocationVO, A extends AbstractLocationVO, 
          C extends AbstractCarrierVO> {
          	
          	protected Long id;
          	protected String status;
          	protected S site;
          	protected D departureLocation;
          	protected A arrivalLocation;
          	protected C carrier;
          I hope this clarifies the problem.

          Many thanks
          Last edited by ssalmon; 17 Feb 2014, 00:51.

          Comment


            #6
            Sorry, you've actually muddied the water further.

            The only instance you've got of setting javaClass sets it to AirsiteVO not FlightVO. Setting javaClass to FlightVO seems to be what you actually want. If you set javaClass to AirsiteVO, you would not expect a FlightVO object to be created and provided.

            If you think you've got your settings correct, please show them, along with the definitions of the classes involved - you have variously talked about FlightVO extending from AirsiteVO or extending from an abstract class that is just parameterized by AirsiteVO - these are different scenarios.

            Comment

            Working...
            X