As part of a PoC, I am currently trying to build a prototype for a side-by-side extension of S/4HANA Cloud, consisting of two layers: A SAPUI5 Frontend decoupled from a Java backend using the S/4HANA Cloud SDK.
On the whole it works great as well. But I often had trouble with the UPDATE commands, so I wrote a small servlet for demo purposes. Now I always get the same exception during the update, namely "Error while parsing the metadata".
I have already tried everything and now have no idea what could be the trigger for this exception.
I was trying to add more dependencies in the pom.xml, but that was without success. Also unsuccessful was the attempt to get all fields with the GET command and to update the filled object. The ETag is also not the problem, this is handled since the latest release by the "versionIdentifier" excellent.
If one of you has any idea of where my mistake lies, I would be very grateful!
Thanks in advance for your help!
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Test-Run: UPDATE
response.getWriter().write("Test-Run: UPDATE" + "\n");
// Prepare the S/4HANA Cloud Service
DefaultSalesOrderService service = new DefaultSalesOrderService();
// Prepare the required Variables
String salesOrderKey = "1";
String deliveryBlockReason = "01";
SalesOrder salesOrder;
try {
// Get the Sales Order
response.getWriter().write("Step 1: Get old data.." + "\n");
salesOrder = service.getSalesOrderByKey(salesOrderKey).select(SalesOrder.DELIVERY_BLOCK_REASON).execute();
// Output: OLD DATA
response.getWriter().write(new Gson().toJson(salesOrder) + "\n");
// Change the Data
response.getWriter().write("\n" + "Step 2: Set new data.." + "\n");
salesOrder.setDeliveryBlockReason(deliveryBlockReason);
// Output: NEW DATA
response.getWriter().write(new Gson().toJson(salesOrder) + "\n");
// Save the Changes
response.getWriter().write("\n" + "Step 3: Save new data.." + "\n");
service.updateSalesOrder(salesOrder).execute();
// Success Message
response.getWriter().write("\n" + "Update successful!");
} catch (final ODataException e) {
// Handle Errors
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
response.getWriter().write("\n" + "Update failed!" + "\n");
response.getWriter().write("Error Code: " + e.getCode() + "\n");
response.getWriter().write("Message: " + e.getMessage() + "\n");
}
}
Test-Run: UPDATE
Step 1: Get old data..
{"DeliveryBlockReason":"","versionIdentifier":"W/\"datetimeoffset\u00272017-06-19T08%3A31%3A55.6635100Z\u0027\""}
Step 2: Set new data..
{"DeliveryBlockReason":"01","versionIdentifier":"W/\"datetimeoffset\u00272017-06-19T08%3A31%3A55.6635100Z\u0027\""}
Step 3: Save new data..
Update failed!
Error Code: null
Message: Error while parsing the metadata.
First of all, thanks for your help!
I reprogrammed the code a bit and implemented Henning's workaround. At first glance, everything seems to work. There are no exceptions and no warnings.
However, in the backend you can see that, that the actual values remain unchanged. Would you have another advice for me?
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Test-Run: UPDATE
response.getWriter().write("Test-Run: UPDATE" + "\n");
// Prepare the S/4HANA Cloud Service
DefaultSalesOrderService service = new DefaultSalesOrderService();
// Prepare the Sales Order Object
SalesOrder salesOrder = null;
// Prepare the required Variables
String salesOrderKey = "163";
// GET
try {
salesOrder = service.getSalesOrderByKey(salesOrderKey).select(SalesOrder.ALL_FIELDS).execute();
// Success Message
response.getWriter().write("\n" + "GET successful!:" + "\n");
// Output: OLD DATA
response.getWriter().write("Old Data:" + "\n");
response.getWriter().write(new Gson().toJson(salesOrder) + "\n");
} catch (ODataException e) {
// Handle Errors
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
response.getWriter().write("\n" + "GET failed!" + "\n");
response.getWriter().write("| Error Code: " + e.getCode() + "\n");
response.getWriter().write("| Message: " + e.getMessage() + "\n");
}
// CHANGE
salesOrder.setSalesOrderType("SO");
// Success Message
response.getWriter().write("\n" + "CHANGE successful!:" + "\n");
// Output: NEW DATA
response.getWriter().write("New Data:" + "\n");
response.getWriter().write(new Gson().toJson(salesOrder) + "\n");
// UPDATE
try {
// Workaround - Henning Heitkötter -
// https://stackoverflow.com/questions/49862888/unknown-exception-null-error-while-parsing-the-metadata-while-executing-defa
SalesOrderUpdateFluentHelper updateHelper = new SalesOrderUpdateFluentHelper(salesOrder) {
@Override
public ODataUpdateRequest toQuery() {
ODataUpdateRequestBuilder requestBuilder = getQueryBuilder()
.withErrorHandler(new ODataVdmErrorResultHandler());
getEntity().setSalesOrder(null);
final Map<String, Object> params = new ODataJsonMapResolver(getEntity()).withoutNullValues();
return requestBuilder.withBodyAsMap(params).build();
}
};
// EXECUTE
updateHelper.execute();
// Success Message
response.getWriter().write("\n" + "UPDATE successful!" + "\n");
} catch (ODataException e) {
// Handle Errors
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
response.getWriter().write("\n" + "UPDATE failed!" + "\n");
response.getWriter().write("| Error Code: " + e.getCode() + "\n");
response.getWriter().write("| Message: " + e.getMessage() + "\n");
}
}
Test-Run: UPDATE
GET successful!:
Old Data:
{"SalesOrder":"163","SalesOrderType":"OR","SalesOrganization":"1010","DistributionChannel":"10","OrganizationDivision":"00","SalesGroup":"","SalesOffice":"","SalesDistrict":"","SoldToParty":"1000355","CreationDate":1516752000000,"CreatedByUser":"CB9980000321","LastChangeDateTime":1516793069586,"PurchaseOrderByCustomer":"110","CustomerPurchaseOrderType":"","CustomerPurchaseOrderDate":1516752000000,"SalesOrderDate":1516752000000,"TotalNetAmount":35.00,"TransactionCurrency":"EUR","SDDocumentReason":"","PricingDate":1516752000000,"RequestedDeliveryDate":1516752000000,"ShippingCondition":"","CompleteDeliveryIsDefined":false,"ShippingType":"","HeaderBillingBlockReason":"","DeliveryBlockReason":"","IncotermsClassification":"CFR","IncotermsTransferLocation":"DE","IncotermsLocation1":"DE","IncotermsLocation2":"","IncotermsVersion":"","CustomerPaymentTerms":"0001","PaymentMethod":"","OverallSDProcessStatus":"A","TotalCreditCheckStatus":"","OverallTotalDeliveryStatus":"","OverallSDDocumentRejectionSts":"A","versionIdentifier":"W/\"datetimeoffset\u00272018-01-24T11%3A24%3A29.5861550Z\u0027\"","AssignmentReference":""}
CHANGE successful!:
New Data:
{"SalesOrder":"163","SalesOrderType":"SO","SalesOrganization":"1010","DistributionChannel":"10","OrganizationDivision":"00","SalesGroup":"","SalesOffice":"","SalesDistrict":"","SoldToParty":"1000355","CreationDate":1516752000000,"CreatedByUser":"CB9980000321","LastChangeDateTime":1516793069586,"PurchaseOrderByCustomer":"110","CustomerPurchaseOrderType":"","CustomerPurchaseOrderDate":1516752000000,"SalesOrderDate":1516752000000,"TotalNetAmount":35.00,"TransactionCurrency":"EUR","SDDocumentReason":"","PricingDate":1516752000000,"RequestedDeliveryDate":1516752000000,"ShippingCondition":"","CompleteDeliveryIsDefined":false,"ShippingType":"","HeaderBillingBlockReason":"","DeliveryBlockReason":"","IncotermsClassification":"CFR","IncotermsTransferLocation":"DE","IncotermsLocation1":"DE","IncotermsLocation2":"","IncotermsVersion":"","CustomerPaymentTerms":"0001","PaymentMethod":"","OverallSDProcessStatus":"A","TotalCreditCheckStatus":"","OverallTotalDeliveryStatus":"","OverallSDDocumentRejectionSts":"A","versionIdentifier":"W/\"datetimeoffset\u00272018-01-24T11%3A24%3A29.5861550Z\u0027\"","AssignmentReference":""}
UPDATE successful!
<entry m:etag="W/"datetimeoffset'2018-01-24T11%3A24%3A29.5861550Z'"">
<id>
...../sap/opu/odata/sap/API_SALES_ORDER_SRV/A_SalesOrder('163')
</id>
<title type="text">A_SalesOrder('163')</title>
<updated>2018-04-18T16:03:24Z</updated>
<category term="API_SALES_ORDER_SRV.A_SalesOrderType" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
<link href="A_SalesOrder('163')" rel="edit" title="A_SalesOrderType"/>
<link href="A_SalesOrder('163')/to_Item" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/to_Item" type="application/atom+xml;type=feed" title="to_Item"/>
<link href="A_SalesOrder('163')/to_Partner" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/to_Partner" type="application/atom+xml;type=feed" title="to_Partner"/>
<link href="A_SalesOrder('163')/to_PricingElement" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/to_PricingElement" type="application/atom+xml;type=feed" title="to_PricingElement"/>
<content type="application/xml">
<m:properties xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
<d:SalesOrder>163</d:SalesOrder>
<d:SalesOrderType>OR</d:SalesOrderType>
<d:SalesOrganization>1010</d:SalesOrganization>
<d:DistributionChannel>10</d:DistributionChannel>
<d:OrganizationDivision>00</d:OrganizationDivision>
<d:SalesGroup/>
<d:SalesOffice/>
<d:SalesDistrict/>
<d:SoldToParty>1000355</d:SoldToParty>
<d:CreationDate>2018-01-24T00:00:00</d:CreationDate>
<d:CreatedByUser>CB9980000321</d:CreatedByUser>
<d:LastChangeDate m:null="true"/>
<d:LastChangeDateTime>2018-01-24T11:24:29.5861550Z</d:LastChangeDateTime>
<d:PurchaseOrderByCustomer>110</d:PurchaseOrderByCustomer>
<d:CustomerPurchaseOrderType/>
<d:CustomerPurchaseOrderDate>2018-01-24T00:00:00</d:CustomerPurchaseOrderDate>
<d:SalesOrderDate>2018-01-24T00:00:00</d:SalesOrderDate>
<d:TotalNetAmount>35.00</d:TotalNetAmount>
<d:TransactionCurrency>EUR</d:TransactionCurrency>
<d:SDDocumentReason/>
<d:PricingDate>2018-01-24T00:00:00</d:PricingDate>
<d:RequestedDeliveryDate>2018-01-24T00:00:00</d:RequestedDeliveryDate>
<d:ShippingCondition/>
<d:CompleteDeliveryIsDefined>false</d:CompleteDeliveryIsDefined>
<d:ShippingType/>
<d:HeaderBillingBlockReason/>
<d:DeliveryBlockReason/>
<d:IncotermsClassification>CFR</d:IncotermsClassification>
<d:IncotermsTransferLocation>DE</d:IncotermsTransferLocation>
<d:IncotermsLocation1>DE</d:IncotermsLocation1>
<d:IncotermsLocation2/>
<d:IncotermsVersion/>
<d:CustomerPaymentTerms>0001</d:CustomerPaymentTerms>
<d:PaymentMethod/>
<d:AssignmentReference/>
<d:OverallSDProcessStatus>A</d:OverallSDProcessStatus>
<d:TotalCreditCheckStatus/>
<d:OverallTotalDeliveryStatus/>
<d:OverallSDDocumentRejectionSts>A</d:OverallSDDocumentRejectionSts>
</m:properties>
</content>
</entry>
The error while parsing metadata occurs because the key field SalesOrder is not set on your entity. You would need to retrieve it as part of the get-by-key as follows, and then you can change the fields that allow changes in SAP S/4HANA, such as the requested delivery date:
SalesOrder salesOrder = service.getSalesOrderByKey(salesOrderKey)
.select(SalesOrder.SALES_ORDER)
.execute()
salesOrder.setRequestedDeliveryDate(Calendar.getInstance());
service.updateSalesOrder(salesOrder).execute();
As of version 1.11.1 of the SAP S/4HANA Cloud SDK, this will only send changed fields (or any field that you explicitly specify via includingFields).
Note: Some fields such as the SalesOrderType or DeliveryBlockReason cannot be changed via the API.
Make sure to use the most recent version of the SAP S/4HANA Cloud SDK, at least version 1.11.1.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With