Using batch requests when interacting with OData v4 services with Olingo

In previous posts, we described how to read data from OData v4 services with Olingo and how to update them. OData (and Olingo) provides a powerful feature to send several calls in a single one (batch requests). We will tackle this feature all along this post.

Initializing the batch manager

The first thing to do to use batch requests is to initialize a batch request. The latter allows to register the requests to send in a single one.

For this, we need to use the class BatchRequestFactory and its method getBatchRequest, as described below:

String serviceRoot = "";
String octetStreamContentType
        = ContentType.APPLICATION_OCTET_STREAM.toContentTypeString();
ODataBatchRequest batchRequest
        = client.getBatchRequestFactory().getBatchRequest(serviceRoot);

Now the request is created, we have access to the batch manager that allows to add requests in the batch request:

BatchManager batchManager = batchRequest.payloadManager();

Adding requests to the batch content manager

The batch content manager allows to add any kind of requests. Both read and update requests are supported and are configured in the same way. We can simply use the method addRequest, as described below:

ODataEntityRequest<ODataEntity> queryRequest = (...)

ODataEntityCreateRequest<ODataEntity> createRequest = (...)

The batch manager allows to go further for requests that update data if the requests are linked.

Defining batch sets

In some cases, requests that update data can be linked together. This means an update request can reference an element that is created by a previous request within the batch request. The problem is that we need a way to reference this element but the identifier isnt known when defining these requests. The changet set feature of batch requests provides a way to configure this using request references

For such use cases, we need to use an ODataChangeset to add requests in it. This can be gotten directly from the batch manager, as described below:

ODataChangeset changeset = payload.addChangeset();

The requests are then added on the change set instead of the batch manager itself. On the change set, we also have a method addRequest to add update requests, as described below:

ODataEntityCreateRequest<ODataEntity> createRequest = (...)

We can notice that only requests to update are allowed in change sets.

What we need now is the way to reference an element previously created or used in the change set. This can be done using the method getLastContentId of the change set.

ODataEntityCreateRequest<ODataEntity> createReq = (...)

int createRequestRef = changeset.getLastContentId();

This method returns an identifier for the request that can be specified when creating an URI with the prefix $ in a way of a variable. For example, for the first request added, it will be $1. See an sample below:

ODataEntityUpdateRequest<ODataEntity> updateReq =
            URI.create("$" + createRequestRef), UpdateType.PATCH, customerChanges);

Now we saw the different ways to add and configure requests within a batch request, lets describe how to extract the responses from the batch response and handle them.

Getting the batch response

The batch request is actually executed when we get the response using its method getResponse. All responses are contained in the body of the batch response. Following code describes this.

ODataBatchResponse response = batchManager.getResponse();
int statusCode = response.getStatusCode();
String statusMessage = response.getStatusMessage();
Iterator<ODataBatchResponseItem> responsesIterator = response.getBody();

We can iterate over the batch response body to get all responses. These responses can be of types:

  • ODataSingleResponseItem: the response only contains one element. We can directly extract the underlying response.
  • ODataChangesetResponseItem: the response contains to change set of responses. In this case, we need to get the list of responses and handle them.

Following code describes how to handle a single response item that corresponds to a retrieve request:

ODataBatchResponseItem item =;
if (item instanceof ODataSingleResponseItem) {
    ODataSingleResponseItem singleItem = (ODataSingleResponseItem) item;
    ODataResponse actualResponse =;
    int actualStatusCode = actualResponse.getStatusCode();
    String actualStatusMessage = actualResponse.getStatusMessage();

    if (actualResponse instanceof ODataRetrieveResponse) {
        ODataRetrieveResponse<ODataEntitySetIterator<ODataEntitySet, ODataEntity>> actualResponse
                = (ODataRetrieveResponse<ODataEntitySetIterator<ODataEntitySet, ODataEntity>>) response;

Once the response is extracted, we are in the normal use case (without batch response). We can notice that the code would be similar for requests that update data.

If we add a change set request, we need to use the following code:

ODataBatchResponseItem item =;
if (item instanceof ODataChangesetResponseItem) {
    ODataChangesetResponseItem changeSetItem = (ODataChangesetResponseItem) item;
    while (changeSetItem.hasNext()) {
        ODataResponse actualResponse =;
        if (actualResponse instanceof ODataEntityUpdateResponse) {
        } else if (actualResponse instanceof ODataEntityCreateResponse) {

Managing errors

We can configure the behavior of the batch manager regarding errors. As a matter of fact, we need to specify if we want to stop the processing if an error for a specific request and continue to handle other responses.

This can be configured within the configuration of the OData client with the property continueOnError, as described below:

boolean defaultContinueOnError = client.getConfiguration().isContinueOnError();
boolean continueOnError = true;

For each request contained in the batch manager, we can check if they are successful in the same way than with single requests based on their status codes. We can notice that the default value of property continueOnError is false.

This entry was posted in Java, Olingo, REST and tagged , , , . Bookmark the permalink.

2 Responses to Using batch requests when interacting with OData v4 services with Olingo

  1. Robert says:

    Nice information.
    But ‘ODataEntitySetIterator’ does’t exists, i think it should be ODataEntitySetIteratorRequest.

  2. Hello,
    Thanks for the blog. It helped me a lot. Could you please explain how to construct the BATCH requests in details. That will be more helpful.

    Thank you

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s