OData and SAP Netweaver Gateway. Part IX. How to Add Multiple Entities in One Operation in OData Service

Multiple Operations in one Call
Share on Facebook0Share on LinkedIn3Tweet about this on TwitterShare on Google+0
Please Share!!

How to add Multiple Entities (Relationship Data) in one Operation in SAP Netweaver and OData Services?

The context for today’s article: I was working on a Fiori PoC (Proof of Concept) for my client where I had to do an update on one of the entity sets with multiple records in one call (one header and multiple line items). I tried with Create Operation on the entity set with multiple records but somehow when the call is made to the model; I can only see the first record is passed to the model always. Again if we want to create or update one header and multiple items then we then have to call Create/Update Header operation and then followed by the call Create/Update Items Operations in back to back multiple calls to Model. This seemed weird!!

After some research, I found that SAP has given an option to do these kinds of operations in an OData Model. This is called DEEP INSERT.

In this exercise, we will learn how we can define and call a DEEP INSERT operation to do an update for business data where there exist a Parent to Child relationship and we want to create all related data in one go i.e. in one call.

For my scenario, I am trying to allocate multiple components to an ALM Order (SAP transaction IW31/32. Popularly for Work Orders). So, in this case, my header is an Order Operation and items are Components allocated to that Operation.

If you go to transaction IW32/33 and open an existing order and navigate to Operations tab and double click on it, it will take you to the details view of that operation where you can add components.

odata service

add multiple rows in an entity without having to call CREATE/UPDATE operations multiple times.

The objective of this discussion is to how to define an operation in the data model so that we can add multiple rows in an entity without having to call CREATE/UPDATE operations multiple times.

If you are new to SAP Netweaver Gateway and OData, please check How you can create your first OData Service?

Service Implementation in my PoC

The data model in my case looks like as follows.

data model

OData Services

The hierarchy that business data in my example model follows is as:

Hierarchy of business data

Service Notification                                   

          Service Order           

              Operation (SR_ServiceOrder_Operation)

                             -> Navigation : SR_ServiceOrder_ComponentSet

                              (Technical Name : SR_SERVICEORDER_COMPONENTSET)

                         Components (SR_ServiceOrder_Component)

Snapshot from the DATA MODEL for identifying the technical name of the navigation highlighted in green above.

DATA MODEL for identifying the technical name

Step 1: Redefine the method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CREATE_DEEP_ENTITY     in the DPC Extension class in backend OData Service.

Hope you know about CRUD Operations. If not, check CRUD Operations in OData.

First of all, we need to create a structure that represents the exact XML representation of the data what is going to be posted by UI.

In order to know what will be the structure the easy way out is:

Go to the SAP Gateway Client and run a $expand query on Header Entity Set to get the data from the Item by a GET method.

/sap/opu/odata/SAP/Z_SERVICE_REQUEST_SRV_03/SR_ServiceOrder_OperationSet(Orderid=’4927185′,Activity=’0010′)?$expand=SR_ServiceOrder_ComponentSet

(In the above example, the SR_ServiceOrder_OperationSet entity set is the Header and the SR_ServiceOrder_ComponentSet entity set is the Item. The section which is (Orderid=’4927185′,Activity=’0010′) is the data with the key for header entity set. Hope you all know these by now. Come on, guys!! We are in Part IX. 🙂

Now when we want to post data we need to change the URI to point to the Header and call POST method. The revised URI from the UI (frontend) should be as follows to let system call DEEP INSERT method.

/sap/opu/odata/SAP/Z_SERVICE_REQUEST_SRV_03/SR_ServiceOrder_OperationSet

Please Note: MODEL identifies to call a CREATE/UPDATE method or a DEEP INSERT method based on the URI. In the URI if MODEL finds the $expand as a parameter then it calls the DEEP INSERT method else normal CREATE/UPDATE operation will be called. So it is very critical for the UI developer to send the URI the in right format.

This query will result into a response. You can use this response as a request and do a POST method. MODEL understands that this POST operation is not a Create (C) or Update (U) post. It will in-turn call the CREATE_DEEP_ENTITY method of the DPC Extension class.

IO_DATA_PROVIDER

In the class, the importing parameter IO_DATA_PROVIDER is used for getting the XML payload from UI. We need to create a local structure which can hold the data provided by the UI payload.

For my requirement, we have created a structure named ‘zpm_sr_service_order_operation’ which has the following structure.

OData handling

The highlighted name of the field which will hold more than one entry MUST have the same name as the technical name of the navigation. (Here we are discussing one level relationship data. In case we need multi-level relationship data then also need to follow the same approach).

DATA MODEL for identifying the technical name

Write the Logic inside the Method: /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CREATE_DEEP_ENTITY

Please Note: In the above definition the Include type zpm_sr_service_order_operation is the entity type of the Operation (Header) and zpm_sr_service_order_comp_tt is a table type of entity type components (Items). The name of the field which would hold the ITEM data (components in our example) should have the same name as the name of the Navigation i.e. SR_ServiceOrder_ComponentSet.

The above code will read the XML payload from UI and do the transformation and fill the local structure lw_data. The lw_data is the deep structure as we have already defined. Going into the deep structure we can call our own custom FM/BAPI to Create or Post data in SAP.

Once the BAPI/custom FM does the data posting we need to fill the right response data in the exporting parameter ER_DEEP_ENTITY. The exporting parameter ER_DEEP_ENTITY will have the same structure as the local variable IW_DATA. We just need to call the standard method ‘COPY_DATA_TO_REF’ available in the extension class as :

copy_data_to_ref

Please Note : The method which we are re-implementing is a generic method and is used for all kinds of DEEP INSERT on different entity sets on that service. So we need to write our code within a proper check on IV_ENTITY_SET_NAME. In my case the IV_ENTITY_SET_NAME would the ‘SR_ServiceOrder_OperationSet’, so all my logic should be within the check for this entity set.

Another important thing is about the exception handling in this method. The Method gives two exceptions /IWBEP/CX_MGW_BUSI_EXCEPTION/IWBEP/CX_MGW_TECH_EXCEPTION for reporting any error to the user on UI. Depending on whether it is a business/technical exception use the proper exception class.

In my case, since my API can return failure messages based on some validations built within it , I have handled it as :

Step 2: UI development from SAPUI5 Perspective

Gather all input data which are required to form data then format data according to entity set and navigation as per cardinality maintained in service. If it mismatches XML will not able to parse. There isn’t any limitation mentioned by SAP for Deep Entity Create set. Here we tried with 4 level Deep Entity creation.

Data need to be formed in format of parent child relationship like shown below:

sapui5

CreateData: Root Element(1:1)

requestChildSO: Child of CreateData(1:1)

operationChild: Child of requestChildSO(1:n)

child:               Child of operationChild(1:n)

nth level

Also Read: An ABAPers Struggle during his/her first SAPUI5 App Development.

It can go to nth level deep. So, there is no limitation. CreateData will parse as XML similarly XML input required in service for creation.
sapui5 for abapersCall Model for the creation of Data, here EntitySet is root Parent Entity set.

Call Model for creation of Data

Download the Source Code Here.

Hope this article will help you when you are in the same situation like I was. SAPUI5 and OData are new to all of us and we all are learning some new trick every day. If you have anything which you figured out very recently in SAP, please do share with you. We would be happy to publish it in your name.

We put a lot of effort in conceptualizing, testing and writing each and every article. If you could pass this link to at least 5 colleagues/friends who you think would benefit from our post, it would be a great favor to our team. We want our articles to reach to as many audiences as possible so that everyone would benefit and our team would remain motivated and our work does not get lost in this huge ocean of the internet.

Please, please share our post in your professional and social media and introduce your friends/colleagues/co-workers to our blog page.

Share on Facebook0Share on LinkedIn3Tweet about this on TwitterShare on Google+0
Please Share!!

About the Author

Chinmaya Das
Chinmaya Das

Qualification: M.Tech from IIT Kharagpur, India.
SAP ABAP Experience since 2006.

Find more about him on LinkedIn.

4 Comments on "OData and SAP Netweaver Gateway. Part IX. How to Add Multiple Entities in One Operation in OData Service"

  1. Thank you for your answer.
    My problem is that I can not create an association for three ‘entity types’ because each one has equal key fields. Some of these key fields are common. The keys of the linked entity sets must be the same. If not, the system displays the message “All keys of the principal entity should be mapped in referential constraint”.

  2. Good article 🙂
    I have a question. To create ‘deep insert’ we need to create an association first? And then this association must be selected in the navigation properties in the ‘Relationship Name’ field. Well I understand that?
    When creating association, the child object must always cover all the key fields of the parent object? What if we have three ‘Entity Type’ and each one will contain additional key fields? How do I combine one ‘Entity Type’ with two others?
    Regards
    Luk

    • Hi Luk,

      This is fairly good assumption that to create dependent entities in a DEEP INSERT method you need to create all entities and the associations first. Because when you POST the data from UI system is going to check against the Model and see if the relationship exists via associations. If not it will give exceptions. In UI we use the name of the ‘Navigation’ to call out the dependent entity.

      When we create associations we need to provide the right keys that bind the parent with the child. In my POC we have 4 different entity types with related key fields from header to all item levels. So when you are creating DEEP INSERT method you just need to pass the required field information as in the DPC Extension method you need to write your own code as how you want to handle this data. Some times we pass dummy data in the key fields to just satisfy the model, but you may / may not be using it. A dummy data can be any thing which is syntactically correct.

      Hope this answers your query. In case it is not please give me your issue in a example which will help me to understand your issue better.

      • Thank you for your answer.
        My problem is that I can not create an association for three ‘entity types’ because each one has different key fields. Some of these key fields are common. The keys of the linked entity sets must be the same. If not, the system displays the message “All keys of the principal entity should be mapped in referential constraint”.

Leave a Reply to Luk Cancel reply

Your email address will not be published.


*