In a previous post, we saw how to access data of OData v4 services with Olingo (see https://templth.wordpress.com/2014/12/03/accessing-odata-v4-service-with-olingo/). We will focus now on how to manipulate these data.
We dont remind here how to configure Olingo in the project and to get an instance of the client. Please refer to the previous post for more details.
In a first time, we will describe how to implement requests to add, update or delete elements. We tackle then how to build the content to provide when adding or updating elements.
For this post, we use the demo OData v4 service provided by the platform services.odata.org
. This service provides read / write accesses.
Implementing CUD operations
In this section, we will describe how to add, update and delete data with Olingo. This is commonly named CUD (Create Update Delete operations). We dont focus on the way to create an instance of the class ODataEntity
. We tackle this aspect later according to what we want to do.
We way to create and execute requests to update elements on OData v4 services follows the same style than for retrieve requests. The OData client of Olingo is used to get the right request factory, the CUDRequestFactory
one. Using the latter we can the request kind for our processing.
If we want to add an element, it corresponds to a ODataEntityCreateRequest
one. The URI to use for the request is the one of the element type. For example, if we want to a product, we simply need to use the entity set segment Products
in the case of our service.
After executing the request, we can check that the element is successfully created using the status code of the response. Its the case with an HTTP code 201
(Created).
Following code describes how to create an element:
String serviceRoot = "http://services.odata.org/V4/OData/(S(li4s4wcplcgyiy3uvuog1lxl))/OData.svc";
URI productsUri = client.newURIBuilder(serviceRoot)
.appendEntitySetSegment("Products").build();
ODataEntity product = (...)
ODataEntityCreateRequest<ODataEntity> req = client.getCUDRequestFactory()
.getEntityCreateRequest(productsUri, product);
ODataEntityCreateResponse<ODataEntity> res = req.execute();
if (res.getStatusCode()==201) {
// Created
}
For updates and deletions, we are now at the level of a particular element. This means that we need to add a key segment with the identifier of the element in the URI.
If we want to update an element, we need to use a request of type ODataEntityUpdateRequest
. In this context, we have two update modes:
- Full updates (replace mode): the element is updated with all the provided content. This replaces the existing content of the element. The mode
UpdateType.REPLACE
is used in this case. - Partial updates (patch mode): only the specified content in the request will be updated in the existing element. Other parts of the element remains the same. This is based under the hood on the HTTP method
PATCH
. The modeUpdateType.PATCH
is used in this case.
After executing the request, we can check that the element is successfully updated using the status code of the response. Its the case with an HTTP code 204
(No Content).
Following code describes how to partially update an element:
String serviceRoot = "http://localhost:8080/V4/OData/(S(li4s4wcplcgyiy3uvuog1lxl))/OData.svc";
URI productsUri = client.newURIBuilder(serviceRoot)
.appendEntitySetSegment("Products")
.appendKeySegment(1000).build();
ODataEntity productUpdates = (...)
ODataEntityUpdateRequest<ODataEntity> req = client
.getCUDRequestFactory().getEntityUpdateRequest(productsUri,
UpdateType.PATCH, productUpdates);
ODataEntityUpdateResponse<ODataEntity> res = req.execute();
if (res.getStatusCode()==204) {
// Updated
}
Deleting elements simply corresponds to execute a request of type ODataEntityDeleteRequest
.
After executing the request, we can check that the element is successfully deleted using the status code of the response. Its the case with an HTTP code 204
(No Content).
Following code describes how to delete an element:
String serviceRoot = "http://localhost:8080/V4/OData/(S(li4s4wcplcgyiy3uvuog1lxl))/OData.svc";
URI productsUri = client.newURIBuilder(serviceRoot)
.appendEntitySetSegment("Products")
.appendKeySegment(1000).build();
ODataDeleteResponse deleteRes = client.getCUDRequestFactory()
.getDeleteRequest(productsUri).execute();
if (deleteRes.getStatusCode()==204) {
// Deleted
}
Now we saw how to execute the different requests, we will focus on the way to create elements involved in such requests.
Initializing elements
Within Olingo client support, entities correspond to exchanged data. They are received when retrieving data but can also be created to send data to the service. The key element is the interface ODataEntity
. Olingo provides an object factory with the class ODataObjectFactory
that allows to create them with its method newEntity
.
Following code describes how to create an empty entity:
ODataEntity product = client.getObjectFactory().newEntity(
new FullQualifiedName("ODataDemo", "Product"));
You can wonder what to specify for the qualified name It depends on the service you use. We need to refer to metadata provided by the target service. For more details, have a look at the section .
Now the entity is created, lets populate it with properties. The object factory used previously also provides methods to create properties and initialize their values.
In the following code, we focus on the creation of primitive properties of several types (integer, string, date, double):
// ID (Edm.Int32)
product.getProperties().add(
client.getObjectFactory().newPrimitiveProperty(
"ID",
client.getObjectFactory().newPrimitiveValueBuilder()
.buildInt32(1000)
));
// Name (Edm.String)
product.getProperties().add(
client.getObjectFactory().newPrimitiveProperty(
"Name",
client.getObjectFactory().newPrimitiveValueBuilder()
.buildString("Product name")
));
// ReleaseDate (Edm.DateTimeOffset)
product.getProperties().add(
client.getObjectFactory().newPrimitiveProperty(
"ReleaseDate",
client.getObjectFactory().newPrimitiveValueBuilder()
.setType(EdmPrimitiveTypeKind.DateTimeOffset)
.setValue(Calendar.getInstance()).build()
));
// Rating (Edm.Int16)
product.getProperties().add(
client.getObjectFactory().newPrimitiveProperty(
"Rating",
client.getObjectFactory().newPrimitiveValueBuilder()
.buildInt32(2)
));
// Price (Edm.Double)
product.getProperties().add(
client.getObjectFactory().newPrimitiveProperty(
"Price",
client.getObjectFactory().newPrimitiveValueBuilder()
.buildDouble(4.5)
));
Using complex properties on elements
Some entities can also use complex properties in addition to primitive properties. For our service, its the case of the entity type PersonDetail
with the property Address
.
In this case, we need to create a complex value with the method newComplexValue
of the object factory. This returns an instance of type ODataComplexValue
. We can add then primitive properties in the way than described in the previous section. The last step is to create the complex property itself based on a name and the complex value using the method newComplexProperty
of the object factory.
Following code describes how to create a complex value and set it for the complex property:
ODataEntity personDetails = client.getObjectFactory().newEntity(
new FullQualifiedName("ODataDemo", "PersonDetail"));
// PersonID (Edm.Int32)
personDetails.getProperties().add(
client.getObjectFactory().newPrimitiveProperty(
"PersonID",
client.getObjectFactory().newPrimitiveValueBuilder()
.buildInt32(1000)
));
(...)
// Address (Complex)
ODataComplexValue<ODataProperty> address =
client.getObjectFactory().newComplexValue("ODataDemo.Address");
// Street (Edm.String)
address.add(client.getObjectFactory().newPrimitiveProperty("Street",
client.getObjectFactory().newPrimitiveValueBuilder().buildString("street")));
(...)
// Country (Edm.String)
address.add(client.getObjectFactory().newPrimitiveProperty("Country",
client.getObjectFactory().newPrimitiveValueBuilder().buildString("country")));
personDetails.getProperties().add(
client.getObjectFactory().newComplexProperty("Address", address));
In the real world, data are linked together. Its also the case with OData entities. In an upcoming post, we will describe how to manage these links.
Pingback: Updating data links of OData v4 services with Olingo | Sandbox for the Web stack
I need to send and save an instance of an object of a class, the server is developed to receive the object.
it is possible to send the object as a parameter?
Can you give an example of Deep Insert using Olingo?