0

I am using VDM to get the navigation property which has multiplicity as 0..1.

Whenever the response returned from S4 is 0 (that is "204 No Content"), I am getting a NullPointerException.

HeaderCDSForPRForGuidedBuying requisitionHeader = isActiveEntity ? readActivatedHeader(purchaseRequisition) : readHeaderInternal(draftUUID);
    GuidedProcurementDeliveryAddressAtHeader requisitionHeaderAddress;

    requisitionHeaderAddress = requisitionHeader.getGuidedProcmtReqnDelivAddrOrFetch();

    return S4ToGBServiceMapper.mapToRequisitionHeader(requisitionHeader, requisitionHeaderAddress);

Here requisitionHeader.getGuidedProcmtReqnDelivAddrOrFetch(); is the navigation entity which is resulting in "204 No Content" from S4 whenever there are no data.

Metadata of the entity

    <EntityType Name="C_GuidedProcmtReqnHdrTPType" sap:label="Header CDS 
     for PR for guided buying" sap:content-version="1">
<Key> 
<PropertyRef Name="PurchaseRequisition"/>
<PropertyRef Name="DraftUUID"/>
<PropertyRef Name="IsActiveEntity"/>
</Key>
<Property Name="Activation_ac" Type="Edm.Boolean" sap:label="Dyn. Action Control" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
<Property Name="Edit_ac" Type="Edm.Boolean" sap:label="Dyn. Action Control" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
<Property Name="Preparation_ac" Type="Edm.Boolean" sap:label="Dyn. Action Control" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
<Property Name="Validation_ac" Type="Edm.Boolean" sap:label="Dyn. Action Control" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
<Property Name="PurReqnDescription_fc" Type="Edm.Byte" sap:label="Dyn. Field Control" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
<Property Name="PurReqnSSPRequestor_fc" Type="Edm.Byte" sap:label="Dyn. Field Control" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
<Property Name="PurchaseRequisition" Type="Edm.String" Nullable="false" MaxLength="10" sap:display-format="UpperCase" sap:label="Purchase requisition" sap:quickinfo="Purchase requisition number" sap:value-list="standard"/>
<Property Name="PurReqnDescription" Type="Edm.String" MaxLength="40" sap:field-control="PurReqnDescription_fc" sap:label="Purchase Requisition Name" sap:quickinfo="Short Text"/>
<Property Name="PurReqnSSPRequestor" Type="Edm.String" MaxLength="60" sap:field-control="PurReqnSSPRequestor_fc" sap:label="Requestor" sap:value-list="standard"/>
<Property Name="PurReqnSSPAuthor" Type="Edm.String" MaxLength="12" sap:display-format="UpperCase" sap:label="Author" sap:quickinfo="Author of Requisition"/>
<Property Name="PurchaseRequisitionType" Type="Edm.String" MaxLength="4" sap:display-format="UpperCase" sap:label="Document Type" sap:quickinfo="Purchase Requisition Document Type"/>
<Property Name="CreationDate" Type="Edm.DateTime" Precision="0" sap:display-format="Date" sap:label="Created On"/>
<Property Name="EmployeeFullName" Type="Edm.String" MaxLength="80" sap:label="Requested By" sap:quickinfo="Full Name of Person"/>
<Property Name="PurReqnOrigin" Type="Edm.String" MaxLength="1" sap:display-format="UpperCase" sap:label="Creation indicator" sap:quickinfo="Creation indicator (purchase requisition/schedule lines)"/>
<Property Name="PurReqnLifeCycleStatus" Type="Edm.String" MaxLength="2" sap:display-format="UpperCase" sap:label="LifeCycle Status" sap:quickinfo="Purchase requistion status" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
<Property Name="PurReqnLifeCycleStatusName" Type="Edm.String" MaxLength="60" sap:label="Status" sap:quickinfo="Short Text for Fixed Values" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
<Property Name="NumberOfItems" Type="Edm.Int32" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
<Property Name="TotalNetAmount" Type="Edm.Decimal" Precision="16" Scale="3" sap:unit="Currency" sap:label="Total Net Value" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
<Property Name="Currency" Type="Edm.String" MaxLength="5" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false" sap:semantics="currency-code"/>
<Property Name="IsSrchEnabled" Type="Edm.Boolean" sap:display-format="UpperCase" sap:label="Hide Search Bar" sap:creatable="false" sap:updatable="false"/>
<Property Name="IsExtPurgScenario" Type="Edm.Boolean" sap:display-format="UpperCase" sap:label="Is External Purch." sap:quickinfo="Indicator for external purchasing scenario" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
<Property Name="IsOnBehalfCart" Type="Edm.String" MaxLength="1" sap:display-format="UpperCase" sap:label="Shop On Behalf Ind." sap:quickinfo="Shop on behalf indicator"/>
<Property Name="PurReqnIsCopyDraft" Type="Edm.Boolean" sap:display-format="UpperCase" sap:label="Draft Is Copied" sap:quickinfo="Draft is copied from active document"/>
<Property Name="BusinessUser" Type="Edm.String" MaxLength="12" sap:display-format="UpperCase" sap:label="User ID"/>
<Property Name="PurReqnIsCreatedInExpertMode" Type="Edm.Boolean" sap:display-format="UpperCase" sap:label="PR in Expert Mode" sap:quickinfo="PR Created in Expert Mode"/>
<Property Name="AccountAssignmentCategory" Type="Edm.String" MaxLength="1" sap:display-format="UpperCase" sap:label="Acct Assignment Cat." sap:quickinfo="Account Assignment Category" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
<Property Name="AcctAssignmentCategoryName" Type="Edm.String" MaxLength="20" sap:label="AcctAssgntCateg Desc" sap:quickinfo="Account Assignment Category Description" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
<Property Name="PrimaryCostObject" Type="Edm.String" MaxLength="30" sap:display-format="UpperCase" sap:label="Primary Cost Object" sap:quickinfo="Account Assignment Primary Cost Object" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
<Property Name="PrimaryCostObjectName" Type="Edm.String" MaxLength="60" sap:display-format="UpperCase" sap:label="Prim. Cost Obj. Name" sap:quickinfo="Account Assignment Primary Cost Object Name" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
<Property Name="DeliveryDurationInDays" Type="Edm.Decimal" Precision="3" Scale="0" sap:label="Delivery time (days)" sap:quickinfo="Delivery time in days" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
<Property Name="DeliveryTime" Type="Edm.Decimal" Precision="3" Scale="0" sap:label="Delivery time (days)" sap:quickinfo="Delivery time in days" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
<Property Name="DeliveryDate" Type="Edm.DateTime" Precision="0" sap:display-format="Date" sap:label="Delivery date" sap:quickinfo="Item delivery date" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
<Property Name="HasDraftEntity" Type="Edm.Boolean" sap:display-format="UpperCase" sap:label="Has Draft" sap:heading="" sap:quickinfo="" sap:creatable="false" sap:updatable="false"/>
<Property Name="DraftUUID" Type="Edm.Guid" Nullable="false" sap:label="Key" sap:heading="" sap:quickinfo="" sap:creatable="false" sap:updatable="false"/>
<Property Name="DraftEntityCreationDateTime" Type="Edm.DateTimeOffset" Precision="7" sap:label="Draft Created On" sap:heading="" sap:quickinfo="" sap:creatable="false" sap:updatable="false"/>
<Property Name="DraftEntityLastChangeDateTime" Type="Edm.DateTimeOffset" Precision="7" sap:label="Draft Last Changed On" sap:heading="" sap:quickinfo="" sap:creatable="false" sap:updatable="false"/>
<Property Name="HasActiveEntity" Type="Edm.Boolean" sap:display-format="UpperCase" sap:label="Has active" sap:heading="" sap:quickinfo="" sap:creatable="false" sap:updatable="false"/>
<Property Name="IsActiveEntity" Type="Edm.Boolean" Nullable="false" sap:display-format="UpperCase" sap:label="Is active" sap:heading="" sap:quickinfo="" sap:creatable="false" sap:updatable="false"/>
<NavigationProperty Name="DraftAdministrativeData" Relationship="MMPUR_REQ_GPR_MAINTAIN_SRV.assoc_76A4502D0F516EE52DD3CBBBE346E4D9" FromRole="FromRole_assoc_76A4502D0F516EE52DD3CBBBE346E4D9" ToRole="ToRole_assoc_76A4502D0F516EE52DD3CBBBE346E4D9"/>
<NavigationProperty Name="SiblingEntity" Relationship="MMPUR_REQ_GPR_MAINTAIN_SRV.assoc_3CC1A0E5A29B95AA58385E4B4E670133" FromRole="FromRole_assoc_3CC1A0E5A29B95AA58385E4B4E670133" ToRole="ToRole_assoc_3CC1A0E5A29B95AA58385E4B4E670133"/>
<NavigationProperty Name="to_GuidedProcmtReqnDelivAddr" Relationship="MMPUR_REQ_GPR_MAINTAIN_SRV.assoc_ABFFAA8E73382AA60F058244C4ABBB35" FromRole="FromRole_assoc_ABFFAA8E73382AA60F058244C4ABBB35" ToRole="ToRole_assoc_ABFFAA8E73382AA60F058244C4ABBB35"/>
<NavigationProperty Name="to_GuidedProcmtReqnUserDefaults" Relationship="MMPUR_REQ_GPR_MAINTAIN_SRV.assoc_1579C23A5F4ED87BDC6BD58F2005A338" FromRole="FromRole_assoc_1579C23A5F4ED87BDC6BD58F2005A338" ToRole="ToRole_assoc_1579C23A5F4ED87BDC6BD58F2005A338"/>
<NavigationProperty Name="to_Purchaserequisitionitem_Wd" Relationship="MMPUR_REQ_GPR_MAINTAIN_SRV.assoc_3F09BE43BBC7F408BF50540B885968FB" FromRole="FromRole_assoc_3F09BE43BBC7F408BF50540B885968FB" ToRole="ToRole_assoc_3F09BE43BBC7F408BF50540B885968FB"/>
<NavigationProperty Name="to_PurReqnEmplByCoOfAuthorVH" Relationship="MMPUR_REQ_GPR_MAINTAIN_SRV.assoc_F51CC3D827FD02E8485693F0D8E2BECB" FromRole="FromRole_assoc_F51CC3D827FD02E8485693F0D8E2BECB" ToRole="ToRole_assoc_F51CC3D827FD02E8485693F0D8E2BECB"/>
<NavigationProperty Name="to_SSPReqnConfiguration" Relationship="MMPUR_REQ_GPR_MAINTAIN_SRV.assoc_8453857C8C3E316B4D665A8FF57BD512" FromRole="FromRole_assoc_8453857C8C3E316B4D665A8FF57BD512" ToRole="ToRole_assoc_8453857C8C3E316B4D665A8FF57BD512"/>
</EntityType>

Here the problem is for navigation

<NavigationProperty Name="to_GuidedProcmtReqnDelivAddr" Relationship="MMPUR_REQ_GPR_MAINTAIN_SRV.assoc_ABFFAA8E73382AA60F058244C4ABBB35" FromRole="FromRole_assoc_ABFFAA8E73382AA60F058244C4ABBB35" ToRole="ToRole_assoc_ABFFAA8E73382AA60F058244C4ABBB35"/>

<Association Name="assoc_ABFFAA8E73382AA60F058244C4ABBB35" sap:content-version="1">
<End Type="MMPUR_REQ_GPR_MAINTAIN_SRV.C_GuidedProcmtReqnHdrTPType" Multiplicity="1" Role="FromRole_assoc_ABFFAA8E73382AA60F058244C4ABBB35"/>
<End Type="MMPUR_REQ_GPR_MAINTAIN_SRV.C_GuidedProcmtReqnDelivAddrType" Multiplicity="0..1" Role="ToRole_assoc_ABFFAA8E73382AA60F058244C4ABBB35"/>
</Association>
medha
  • 3
  • 2
  • Can you pls provide the complete stack trace? – Emdee Oct 04 '19 at 11:45
  • I am not able to get the complete stack trace, as I am getting NullPointerException at ODataQueryResult.java -> inputStream = httpResponse.getEntity().getContent(); , here httpResponse.getEntity() is returning Null for 204 No Content response, and when getContent() is tried to invoke its throwing NullPointerException. – medha Oct 07 '19 at 04:12
  • I have added the metadata for the entity. While I was debugging I found that entitymetadata is null for this scenario in internalExecute method of ODataQuery class, hence there is error while creating new ODataQueryResult(entitymetadata, httpResponse, isMediaRequest); at line 247 ODataQuery class(inside private internalExecute method) – medha Oct 07 '19 at 04:27

1 Answers1

0

Thanks for your detailed question.

It seems like you indeed have found a bug in one of the indirectly consumed components related to SAP Cloud SDK. I have created an incident (#1970496164) in the ticketing system. It's not clear when precisely this NullPointerException will be fixed, hopefully in one of the next upcoming versions.

In the meantime, I'd suggest using the Try API of the VAVR library as a workaround - to handle the error at runtime.

import io.vavr.control.Try;

// ...

@Nonnull
HeaderCDSForPRForGuidedBuying requisitionHeader;

@Nullable
GuidedProcurementDeliveryAddressAtHeader requisitionHeaderAddress;

// tolerant error handling
requisitionHeaderAddress = Try.of(requisitionHeader::getGuidedProcmtReqnDelivAddrOrFetch).getOrNull();

return S4ToGBServiceMapper.mapToRequisitionHeader(requisitionHeader, requisitionHeaderAddress);

(assuming your mapToRequisitionHeader method expects the second parameter to be @Nullable)

Add the dependency to your pom:

<dependency>
  <groupId>io.vavr</groupId>
  <artifactId>vavr</artifactId>
  <version>0.10.2</version>
</dependency>

As an alternative to my proposal, you could just use the bulky try-catch block of course.

Alexander Dümont
  • 903
  • 1
  • 5
  • 9