作为PoC的一部分,我目前正在尝试为S/4HANA Cloud的并排扩展构建原型(prototype),该原型(prototype)包括两层:使用 S/4HANA Cloud SDK与Java后端分离的SAPUI5前端。

总的来说,它也很好。但是我经常在使用UPDATE命令时遇到麻烦,因此我为演示目的编写了一个小的servlet。现在,在更新过程中,我总是会遇到相同的异常,即“解析元数据时出错”

我已经尝试了所有方法,现在不知道该异常的触发因素是什么。

我试图在pom.xml中添加更多的依赖项,但这没有成功。尝试使用GET命令获取所有字段并更新填充的对象也是不成功的。 ETag也不是问题,自“versionIdentifier”最新版本以来,该问题得到了很好的解决。

如果你们中的一个人知道我的错误在哪里,我将不胜感激!

在此先感谢您的帮助!

[OLD]代码段:公共(public)类UpdateService扩展了HttpServlet

@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");
    }
}

[OLD] Http-响应
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.

更新-2018-04-18

首先,感谢您的帮助!

我对代码进行了一些重新编程,并实现了Henning的变通办法。乍一看,一切似乎都正常。没有异常(exception),也没有警告。

但是,在后端您可以看到,实际值保持不变。您还有其他建议吗?

[NEW]代码段:公共(public)类UpdateService扩展了HttpServlet
    @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");
    }

}

[NEW] Http-Response
    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!

[NEW] S/4HANA Cloud API
    <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>

最佳答案

解析元数据时发生错误,因为未在您的实体上设置关键字段SalesOrder。您将需要按以下方式获取它作为“获取 key ”的一部分,然后可以更改允许更改SAP S/4HANA的字段,例如请求的交货日期:

SalesOrder salesOrder = service.getSalesOrderByKey(salesOrderKey)
    .select(SalesOrder.SALES_ORDER)
    .execute()
salesOrder.setRequestedDeliveryDate(Calendar.getInstance());
service.updateSalesOrder(salesOrder).execute();

从SAP S/4HANA Cloud SDK的version 1.11.1开始,这将仅发送更改的字段(或您通过includeFields明确指定的任何字段)。

注意:某些字段(例如SalesOrderType或DeliveryBlockReason)无法通过API进行更改。

确保使用最新版本的SAP S/4HANA Cloud SDK,至少使用1.11.1版本。

10-06 14:30