We are using SAP SDK 3.25.0 and calling a batch request Read query passing some filters. I am getting the response of all the records and it can be seen that the filter is not working properly.
I have referred this blog here but I am getting the same issue of decode URL issue YY1_QuantityContractTracki?$filter=((CustomerName eq %27Ford%27) and (SalesSchedulingAgreement eq %270030000141%27)) and (PurchaseOrderByCustomer eq %27TEST%27)&$select=SalesSchedulingAgreement,PurchaseOrderByCustomer,Customer,CustomerName,SalesSchedulingAgreementItem,Material,MaterialByCustomer&$format=json
Below is the query program which I am using.
Am I missing something here. Please let us know Thanks, Arun Pai
final BatchRequestBuilder builder = BatchRequestBuilder.withService("/sap/opu/odata/sap/YY1_QUANTITYCONTRACTTRACKI_CDS");
for (Contract contract : contracts) {
FilterExpression mainFilter = new FilterExpression("CustomerName", "eq", ODataType.of(contract.getCustomerName()))
.and(new FilterExpression("SalesSchedulingAgreement", "eq", ODataType.of(contract.getSchAgrmntNo())))
.and(new FilterExpression("PurchaseOrderByCustomer", "eq", ODataType.of(contract.getCustRefNo())));
final ODataQuery oDataQuery = ODataQueryBuilder
.withEntity(sapConfig.getEssentialsContractServiceUrl(),
sapConfig.getEssentialsContractListEntity())
.select("SalesSchedulingAgreement", "PurchaseOrderByCustomer", "Customer", "CustomerName",
"SalesSchedulingAgreementItem", "Material", "MaterialByCustomer")
.filter(mainFilter)
.build();
builder.addQueryRequest(oDataQuery);
}
final BatchRequest batchRequest = builder.build();
final BatchResult batchResult = batchRequest.execute(httpClient);
Update
I have changed the version to 3.35.0 today with connectivity version 1.40.11 but it did'nt work either. Below is the log request which gets printed in the console
2021-01-15 19:15:03.831 INFO 42640 --- [io-8084-exec-10] c.s.c.s.o.c.impl.BatchRequestImpl : --batch_123 Content-Type: application/http Content-Transfer-Encoding: binary
GET YY1_QuantityContractTracki?%24filter%3D%28%28CustomerName+eq+%2527Ford27%29+and+%28SalesSchedulingAgreement+eq+%25270030000141%2527%29%29+and+%28PurchaseOrderByCustomer+eq+%2527TEST%2527%29%26%24select%3DSalesSchedulingAgreement%2CPurchaseOrderByCustomer%2CCustomer%2CCustomerName%2CSalesSchedulingAgreementItem%2CMaterial%2CMaterialByCustomer%26%24format%3Djson HTTP/1.1 Accept: application/json;odata=verbose
--batch_123--
Update (22.03.2021)
With the release of SAP Cloud SDK 3.41.0
this week we'll enable support for read operations in OData batch requests on the type-safe API. Please find the chapter in the respective documentation.
Example:
BusinessPartnerService service;
BusinessPartnerAddress addressToCreate1;
BusinessPartnerAddress addressToCreate2;
BusinessPartnerFluentHelper requestTenEntities = service.getAllBusinessPartner().top(10);
BusinessPartnerByKeyFluentHelper requestSingleEntity = service.getBusinessPartnerByKey("bupa9000");
BatchResponse result =
service
.batch()
.addReadOperations(requestTenEntities)
.addReadOperations(requestSingleEntity)
.executeRequest(destination);
List<BusinessPartner> entities = result.getReadResult(requestTenEntities);
BusinessPartner entity = result.getReadResult(requestSingleEntity);
Original response:
I'm from the SAP Cloud SDK team. Generally we recommend our users to generate classes for their OData service interactions. This way you can easily make sure that requests are according to specification, while type safety is taken care of.
Unfortunately I cannot help you with the API of BatchRequestBuilder
, BatchRequest
or BatchResult
because they are not directly a part of SAP Cloud SDK and not maintained by us. Instead we suggest our own request builders.
If the generation of classes, as linked above, is not an option for you, then I would suggest to try our expert API featuring the Generic OData Client of SAP Cloud SDK. This is the code that we would also use internally for our generated request builders:
String servicePath = "/sap/opu/odata/sap/YY1_QUANTITYCONTRACTTRACKI_CDS";
ODataRequestBatch requestBatch = new ODataRequestBatch(servicePath, ODataProtocol.V2);
Map<Contract, ODataRequestRead> batchedRequests = new HashMap<>();
// iterate over contracts, construct OData query objects and add them to the OData batch request builder
for (Contract contract : contracts) {
String entityName = sapConfig.getEssentialsContractListEntity();
String serviceUrl = sapConfig.getEssentialsContractServiceUrl();
StructuredQuery structuredQuery = StructuredQuery.onEntity(entityName, ODataProtocol.V2);
structuredQuery.select("SalesSchedulingAgreement", "PurchaseOrderByCustomer", "Customer", "CustomerName", "SalesSchedulingAgreementItem", "Material", "MaterialByCustomer");
structuredQuery.filter(FieldReference.of("SalesSchedulingAgreement").equalTo(contract.getSchAgrmntNo()));
structuredQuery.filter(FieldReference.of("PurchaseOrderByCustomer").equalTo(contract.getCustRefNo()));
String encodedQuery = structuredQuery.getEncodedQueryString();
ODataRequestRead requestRead = new ODataRequestRead(serviceUrl, entityName, encodedQuery, ODataProtocol.V2);
batchedRequests.put(contract, requestRead);
requestBatch.addRead(requestRead);
}
// execute the OData batch request
ODataRequestResultMultipartGeneric batchResult = requestBatch.execute(httpClient);
// extract information from batch response, by referring to the individual OData request references
for( Map.Entry<Contract, ODataRequestRead> requestMapping : batchedRequests.entrySet() ) {
ODataRequestResultGeneric queryResult = batchResult.getResult(requestMapping.getValue());
List<Map<String, Object>> itemsForQuery = queryResult.asListOfMaps();
}
Kind regards
Alexander
Thanks. the above solution worked. I can see the tag @Beta in the Structured query class. Will this get changed??
Correct. Most classes of the Maven module
com.sap.cloud.sdk.datamodel:odata-client
are@Beta
annotated, indicating that some public API may be subject to changes still. As of today this API above is the only option to read OData read responses from a batch result for OData V2. Will this get changed? Yes, most certainly. Either the OData V2 request builder API will be extended or the Generic OData Client (here) will be non-beta. Unfortunately I can't promise a schedule for that. Would such change be critical / urgent for your project?Yes. this is critical as I am using this in our project to make the functionality stable. Can this issue be resolved If I use Odata Generator -VDM Model?? Please suggest
@ArunKumar, we have it in the backlog and as you plan this for production I re-prioritized this to the top. Do you have a time-frame to have this productively released to match your plans? I'll see what we can do then.
We have a release planned around Mid Feb and a dev deadline by first week of Feb. If this can be released around that time, It will be great! The other question of using Odata generator - vdm model as an option, will it work ?