Implementing Batch Operations in OData
- Hello Readers,
In this post I am going to write about how to perform batch operations in OData using ABAP ECC server and SAP NetWeaver Gateway.
Firstly create an table in SE11 like displayed below :
Initially create some entries in the table, like this :
Now go to the transaction SEGW and create an OData project. It should initially display 4 folders :
- Data Model
- Service Implementation
- Runtime Artifacts
- Service Maintenance
Right click on the data model, under import, select from DDIC (Data Dictionary) structure. In the popup that opens, give your table name and create an entity as well as an entity set. Give “USERID” as the primary key.Now generate the runtime artifacts by clicking on the ball-like button in the nav bar.Now your OData project should look something like this :
Now double click on the DPC_EXT class in the runtime artifacts. The following screen should appear.
In this class, the following are the methods that are to be redefined :
- EntitySetName_GET_ENTITY – To output a single record.
- EntitySetName_GET_ENTITY_SET – To output multiple records.
- EntitySetName_CREATE_ENTITY – To create a record.
- EntitySetName_UPDATE_ENTITY – To update existing record.
- EntitySetName_DELETE_ENTITY – To delete existing record.
- /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CHANGESET_BEGIN – For batch operation.
- /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CHANGESET_END – For batch operation.
You dont need to implement any code in the last two methods, just redefine them and activate them. For the other methods, implement the code as given below :
GET_ENTITY :
data wa_key_tab1 type /iwbep/s_mgw_name_value_pair.
read table it_key_tab into wa_key_tab1 index 1.
select single * from zarjun_batch_h into er_entity where userid = wa_key_tab1-value.
GET_ENTITY_SET :
select * from zarjun_batch_h into table et_entityset.
CREATE_ENTITY :
data wa type zcl_zar_batch_mpc=>ts_batch.
io_data_provider->read_entry_data( importing es_data = wa ).
insert into zarjun_batch_h values wa.
UPDATE_ENTITY :
data wa type zcl_zar_batch_mpc=>ts_batch.
io_data_provider->read_entry_data( importing es_data = wa ).
update zarjun_batch_h set name = wa-name
age = wa-age
email = wa-email
country = wa-country
where userid = wa-userid.
DELETE_ENTITY :
data wa type /iwbep/s_mgw_name_value_pair.
read table it_key_tab into wa with key name = 'Userid'.
delete from zarjun_batch_h where userid = wa-value.
Next step, check the code using CTRL + F2 and activate using CTRL + F3.
Now in the service maintenance folder, first register and then maintain the service. Now go to the Gateway Client. The following window should open :
To execute any batch operation, we have to use the $batch URI.
BATCH GET OPERATION
For Single record :
Request URI : path/SERVICE_NAME/$batch
HTTP REQUEST :
--batch
Content-Type: application/http
Content-Transfer-Encoding: binary
Accept: application/json
GET batchSet('01') HTTP/1.1
--batch--
BATCH POST OPERATION
For Single record:
Request URI : path/SERVICE_NAME/$batch
HTTP REQUEST :
--batch
Content-Type: multipart/mixed; boundary=changeset
--changeset
Content-Type: application/http
Content-Transfer-Encoding: binary
POST batchSet HTTP/1.1
Content-Type: application/atom+xml;type=entry
Content-Length: 817
dataserviceversion: 2.0
<?xml version="1.0" encoding="utf-8"?>
<entry xml:base="http://EHP7PRD.sap.in:8048/sap/opu/odata/SAP/ZAR_BATCH_SRV/" xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
<id>http://EHP7PRD.sap.in:8048/sap/opu/odata/SAP/ZAR_BATCH_SRV/batchSet('01')</id>
<title type="text">batchSet('05')</title>
<updated>2017-12-13T09:59:43Z</updated>
<category term="ZAR_BATCH_SRV.batch" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
<link href="batchSet('05')" rel="self" title="batch"/>
<content type="application/xml">
<m:properties>
<d:Userid>05</d:Userid>
<d:Name>Arjun Biswas</d:Name>
<d:Age>91</d:Age>
<d:Email>aa@aa.com</d:Email>
<d:Country>India</d:Country>
</m:properties>
</content>
</entry>
--changeset--
--batch--
For Multiple records:
Request URI : path/SERVICE_NAME/$batch
HTTP REQUEST :
--batch
Content-Type: multipart/mixed; boundary=changeset
--changeset
Content-Type: application/http
Content-Transfer-Encoding: binary
POST batchSet HTTP/1.1
Content-Type: application/xml
Content-Length: 1000
<?xml version="1.0" encoding="utf-8"?>
<entry xml:base="http://EHP7PRD.sap.in:8048/sap/opu/odata/SAP/ZAR_BATCH_SRV/" xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
<id>http://EHP7PRD.sap.in:8048/sap/opu/odata/SAP/ZAR_BATCH_SRV/batchSet('01')</id>
<title type="text">batchSet('05')</title>
<updated>2017-12-13T09:59:43Z</updated>
<category term="ZAR_BATCH_SRV.batch" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
<link href="batchSet('06')" rel="self" title="batch"/>
<content type="application/xml">
<m:properties>
<d:Userid>06</d:Userid>
<d:Name>XXX YYY</d:Name>
<d:Age>91</d:Age>
<d:Email>aa@aa.com</d:Email>
<d:Country>India</d:Country>
</m:properties>
</content>
</entry>
--changeset
Content-Type: application/http
Content-Transfer-Encoding: binary
POST batchSet HTTP/1.1
Content-Type: application/xml
Content-Length: 1000
<?xml version="1.0" encoding="utf-8"?>
<entry xml:base="http://EHP7PRD.sap.in:8048/sap/opu/odata/SAP/ZAR_BATCH_SRV/" xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
<id>http://EHP7PRD.sap.in:8048/sap/opu/odata/SAP/ZAR_BATCH_SRV/batchSet('01')</id>
<title type="text">batchSet('07')</title>
<updated>2017-12-13T09:59:43Z</updated>
<category term="ZAR_BATCH_SRV.batch" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
<link href="batchSet('07')" rel="self" title="batch"/>
<content type="application/xml">
<m:properties>
<d:Userid>07</d:Userid>
<d:Name>VVV VVV</d:Name>
<d:Age>91</d:Age>
<d:Email>aa@aa.com</d:Email>
<d:Country>India</d:Country>
</m:properties>
</content>
</entry>
--changeset--
--batch--
BATCH UPDATE (PUT) OPERATION
For Single record:
Request URI : path/SERVICE_NAME/$batch
HTTP REQUEST :
--batch
Content-Type: multipart/mixed; boundary=changeset
--changeset
Content-Type: application/http
Content-Transfer-Encoding: binary
PUT batchSet('05') HTTP/1.1
Content-Type: application/xml
Content-Length: 130
<?xml version="1.0" encoding="utf-8"?>
<entry xml:base="http://EHP7PRD.sap.in:8048/sap/opu/odata/SAP/ZAR_BATCH_SRV/" xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
<id>http://EHP7PRD.sap.in:8048/sap/opu/odata/SAP/ZAR_BATCH_SRV/batchSet('')</id>
<title type="text">batchSet('')</title>
<updated>2017-12-13T10:11:04Z</updated>
<category term="ZAR_BATCH_SRV.batch" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
<link href="batchSet('')" rel="self" title="batch"/>
<content type="application/xml">
<m:properties>
<d:Userid>05</d:Userid>
<d:Name>HELLO</d:Name>
<d:Age>922</d:Age>
<d:Email>aa@aa223.com</d:Email>
<d:Country>India</d:Country>
</m:properties>
</content>
</entry>
--changeset--
--batch--
For multiple records:
Request URI : path/SERVICE_NAME/$batch
HTTP REQUEST :
--batch
Content-Type: multipart/mixed; boundary=changeset
--changeset
Content-Type: application/http
Content-Transfer-Encoding: binary
PUT batchSet('07') HTTP/1.1
Content-Type: application/xml
Content-Length: 130
<?xml version="1.0" encoding="utf-8"?>
<entry xml:base="http://EHP7PRD.sap.in:8048/sap/opu/odata/SAP/ZAR_BATCH_SRV/" xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
<id>http://EHP7PRD.sap.in:8048/sap/opu/odata/SAP/ZAR_BATCH_SRV/batchSet('')</id>
<title type="text">batchSet('')</title>
<updated>2017-12-13T10:11:04Z</updated>
<category term="ZAR_BATCH_SRV.batch" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
<link href="batchSet('')" rel="self" title="batch"/>
<content type="application/xml">
<m:properties>
<d:Userid>07</d:Userid>
<d:Name>HELLO ALL</d:Name>
<d:Age>922</d:Age>
<d:Email>aa2@aa223.com</d:Email>
<d:Country>India</d:Country>
</m:properties>
</content>
</entry>
--changeset
Content-Type: application/http
Content-Transfer-Encoding: binary
PUT batchSet('06') HTTP/1.1
Content-Type: application/xml
Content-Length: 130
<?xml version="1.0" encoding="utf-8"?>
<entry xml:base="http://EHP7PRD.sap.in:8048/sap/opu/odata/SAP/ZAR_BATCH_SRV/" xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
<id>http://EHP7PRD.sap.in:8048/sap/opu/odata/SAP/ZAR_BATCH_SRV/batchSet('')</id>
<title type="text">batchSet('')</title>
<updated>2017-12-13T10:11:04Z</updated>
<category term="ZAR_BATCH_SRV.batch" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
<link href="batchSet('')" rel="self" title="batch"/>
<content type="application/xml">
<m:properties>
<d:Userid>06</d:Userid>
<d:Name>WELCOME BATCH</d:Name>
<d:Age>19232</d:Age>
<d:Email>aa1a@aa223.com</d:Email>
<d:Country>India</d:Country>
</m:properties>
</content>
</entry>
--changeset--
--batch--
BATCH DELETE OPERATION
For Single record:
Request URI : path/SERVICE_NAME/$batch
HTTP REQUEST :
--batch
content-Type: multipart/mixed;boundary=changeset
--changeset
Content-Type: application/http
Content-Transfer-Encoding: binary
DELETE batchSet('07') HTTP/1.1
--changeset--
--batch--
For multiple records:
Request URI : path/SERVICE_NAME/$batch
HTTP REQUEST :
--batch
content-Type: multipart/mixed;boundary=changeset
--changeset
Content-Type: application/http
Content-Transfer-Encoding: binary
DELETE batchSet('06') HTTP/1.1
--changeset
Content-Type: application/http
Content-Transfer-Encoding: binary
DELETE batchSet('05') HTTP/1.1
--changeset--
--batch--
COMBINING BATCH OPERATIONS :
GET and PUT operation :
--batch
Content-Type: application/http
Content-Transfer-Encoding: binary
Accept: application/json
GET batchSet('01') HTTP/1.1
--batch
Content-Type: multipart/mixed; boundary=changeset
--changeset
Content-Type: application/http
Content-Transfer-Encoding: binary
PUT batchSet('04') HTTP/1.1
Content-Type: application/xml
Content-Length: 130
<?xml version="1.0" encoding="utf-8"?>
<entry xml:base="http://EHP7PRD.sap.in:8048/sap/opu/odata/SAP/ZAR_BATCH_SRV/" xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
<id>http://EHP7PRD.sap.in:8048/sap/opu/odata/SAP/ZAR_BATCH_SRV/batchSet('')</id>
<title type="text">batchSet('')</title>
<updated>2017-12-13T10:11:04Z</updated>
<category term="ZAR_BATCH_SRV.batch" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
<link href="batchSet('')" rel="self" title="batch"/>
<content type="application/xml">
<m:properties>
<d:Userid>05</d:Userid>
<d:Name>WELCOME BATCH</d:Name>
<d:Age>34</d:Age>
<d:Email>aaa@aa.com</d:Email>
<d:Country>India</d:Country>
</m:properties>
</content>
</entry>
--changeset--
--batch--
POST, PUT and DELETE operations together :
--batch
Content-Type: multipart/mixed; boundary=changeset
--changeset
Content-Type: application/http
Content-Transfer-Encoding: binary
POST batchSet HTTP/1.1
Content-Type: application/xml
Content-Length: 130
<?xml version="1.0" encoding="utf-8"?>
<entry xml:base="http://EHP7PRD.sap.in:8048/sap/opu/odata/SAP/ZAR_BATCH_SRV/" xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
<id>http://EHP7PRD.sap.in:8048/sap/opu/odata/SAP/ZAR_BATCH_SRV/batchSet('01')</id>
<title type="text">batchSet('05')</title>
<updated>2017-12-13T11:03:13Z</updated>
<category term="ZAR_BATCH_SRV.batch" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
<link href="batchSet('05')" rel="self" title="batch"/>
<content type="application/xml">
<m:properties>
<d:Userid>05</d:Userid>
<d:Name>Arjun Biswas</d:Name>
<d:Age>91</d:Age>
<d:Email>aa@aa.com</d:Email>
<d:Country>India</d:Country>
</m:properties>
</content>
</entry>
--changeset
Content-Type: application/http
Content-Transfer-Encoding: binary
PUT batchSet('3000000005') HTTP/1.1
Content-Type: application/xml
Content-Length: 130
<?xml version="1.0" encoding="utf-8"?>
<entry xml:base="http://EHP7PRD.sap.in:8048/sap/opu/odata/SAP/ZAR_BATCH_SRV/" xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
<id>http://EHP7PRD.sap.in:8048/sap/opu/odata/SAP/ZAR_BATCH_SRV/batchSet('01')</id>
<title type="text">batchSet('05')</title>
<updated>2017-12-13T11:03:13Z</updated>
<category term="ZAR_BATCH_SRV.batch" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
<link href="batchSet('05')" rel="self" title="batch"/>
<content type="application/xml">
<m:properties>
<d:Userid>05</d:Userid>
<d:Name>Arjun Biswas 1</d:Name>
<d:Age>91</d:Age>
<d:Email>a1a@aa.com</d:Email>
<d:Country>India</d:Country>
</m:properties>
</content>
</entry>
--changeset
Content-Type: application/http
Content-Transfer-Encoding: binary
DELETE batchSet(Userid='04') HTTP/1.1
--changeset--
--batch--
Combining all CRUD methods together :
--batch
Content-Type: application/http
Content-Transfer-Encoding: binary
Accept: application/json
GET batchSet('01') HTTP/1.1
--batch
Content-Type: multipart/mixed; boundary=changeset
--changeset
Content-Type: application/http
Content-Transfer-Encoding: binary
POST batchSet HTTP/1.1
Content-Type: application/xml
Content-Length: 130
<?xml version="1.0" encoding="utf-8"?>
<entry xml:base="http://EHP7PRD.sap.in:8048/sap/opu/odata/SAP/ZAR_BATCH_SRV/" xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
<id>http://EHP7PRD.sap.in:8048/sap/opu/odata/SAP/ZAR_BATCH_SRV/batchSet('01')</id>
<title type="text">batchSet('05')</title>
<updated>2017-12-13T11:03:13Z</updated>
<category term="ZAR_BATCH_SRV.batch" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
<link href="batchSet('04')" rel="self" title="batch"/>
<content type="application/xml">
<m:properties>
<d:Userid>04</d:Userid>
<d:Name>Arjun Biswas </d:Name>
<d:Age>91</d:Age>
<d:Email>aa@aa.com</d:Email>
<d:Country>India</d:Country>
</m:properties>
</content>
</entry>
--changeset
Content-Type: application/http
Content-Transfer-Encoding: binary
PUT batchSet('05') HTTP/1.1
Content-Type: application/xml
Content-Length: 130
<?xml version="1.0" encoding="utf-8"?>
<entry xml:base="http://EHP7PRD.sap.in:8048/sap/opu/odata/SAP/ZAR_BATCH_SRV/" xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
<id>http://EHP7PRD.sap.in:8048/sap/opu/odata/SAP/ZAR_BATCH_SRV/batchSet('01')</id>
<title type="text">batchSet('05')</title>
<updated>2017-12-13T11:03:13Z</updated>
<category term="ZAR_BATCH_SRV.batch" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
<link href="batchSet('05')" rel="self" title="batch"/>
<content type="application/xml">
<m:properties>
<d:Userid>05</d:Userid>
<d:Name>Arjun Biswas 1</d:Name>
<d:Age>91</d:Age>
<d:Email>a1a@aa.com</d:Email>
<d:Country>India</d:Country>
</m:properties>
</content>
</entry>
--changeset
Content-Type: application/http
Content-Transfer-Encoding: binary
DELETE batchSet(Userid='05') HTTP/1.1
--changeset--
--batch--
That’s basically it. Using the above methods you can perform any batch operations on any number of entity sets in one HTTP request only. The output can be both checked at the HTTP Response, a well as from SE11.
You should take care while performing batch operations in the request body as an single space or extra line can cause errors. Many might have faced an issue like below :
This happens even when you miss a line while writing the HTTP Request. Any batch request starts with the “–batch” statement and ends with the “–batch–” statement.
Regards,
Arjun Biswas
Hi Arjun Biswas
thanks for sharing that example, but I wonder what code do I have to type these method:
or just I leave it in blank?
best wishes
Eliu
Hi Eliu Gonzalez,
Thank you for the comment. Yes, you have to leave the two methods blank. Just redefine them and activate your DPC_EXT class. Don't write any code in them.
Regards,
Arjun Biswas
Hi Arjun,
Can you be more specific ? You are saying not to write any code in the below methods
But then where we need to write the below highlighted code, which you have written for - BATCH UPDATE (PUT) OPERATION and what URI we need to give to the Frontend developer to call ?
I have a requirement where we need to approve multiple Sales Orders by selecting from the Master page of the Fiori App. So from ODATA , how can I implement this ?
For multiple records:
Request URI : path/SERVICE_NAME/$batch
HTTP REQUEST :
--batch
Content-Type: multipart/mixed; boundary=changeset
--changeset
Content-Type: application/http
Content-Transfer-Encoding: binary
PUT batchSet('07') HTTP/1.1
Content-Type: application/xml
Content-Length: 130
Hi,
The part you are asking is the load, we use this in /IWFND/GW_CLIENT check how you impliment deep entity type, there also we have load that is needed to update the database.
Below the left part is the load, where you need to use that.
Thank you
Hi Arjun,
When i am posting multiple entries i am getting an error of
Hi Arjun Biswas , are you really able to update records? If you put a breakpoint in your UPDATE_ENTITY method, does it fire up?
When I put breakpoint in CREATE_ENTITY method, it fires up but not for UPDATE_ENTITY.
Thanks in advance.
I experienced this with my PUT method. I specified merge: false and i was able to fire up my UPDATE_ENTITY.
//Create Batch
this.oOdataModel.setUseBatch(true);
for (var count = 0; count <= iCount; count++) {
sPath = "/WorkItemSet(workitemId='" + selectedData[count].workitemId + "')";
this.oOdataModel.update(sPath, selectedData[count], {
method: "PUT",
merge: false,
success: function (data) {
// Do something
},
error: function (e) {
// Do something
}
});
}
this.oOdataModel.submitChanges({
success: function (data, response) {
//Do something here
},
error: function (e) {
//Do something here
}
});
Hi Jumar,
Please refer to my post:
https://answers.sap.com/answers/606516/view.html
thanks for sharing this
Is there any difference for batch calls with Odata V4 services ?