Skip to content

Querying and Modifying Data Using Proxy Classes

Get All Entities of an Entity Set

GET OData.svc/Products HTTP/1.1
List<Product> products = demoService.getProducts();
val products = demoService.products

Get a Specific Entity via Its Key

GET OData.svc/Products(8) HTTP/1.1
DataQuery query = new DataQuery().withKey(Product.key(8)); //Primary Key ID=8
Product product = demoService.getProduct(query);

// For an entity with a composite key (int, string),
// DataQuery query = new DataQuery().withKey(SomeEntity.key(123, “abc”));
val query = DataQuery().withKey(Product.key(8))
val product = demoService.getProduct(query)

Load an Entity

LoadEntity is often used to lazily load navigation properties or the entire set of properties on a detail page

GET OData.svc/Products(8) HTTP/1.1
Product product = new Product();
product.setId(8);
demoService.loadEntity(product); // product will hold the returned entity
val product = Product()
product.Id = 8
eventService.loadEntity(product)

Query an Entity to Return only Primary Key Values in the Result

GET OData.svc/Products?$select=ID HTTP/1.1
DataQuery query = new DataQuery().selectKey();
List<Product> products = demoService.getProducts(query);
val query = DataQuery().selectKey()
val products = demoService.getProducts(query)

Query an Entity Using a Condition on Non-Key Properties

This code sorts data by multiple columns.

GET OData.svc/Products?$filter=substringof('DVD',Name)&$orderby=Name,Price HTTP/1.1
DataQuery query = new DataQuery()
    .filter(Product.name.contains("DVD"))
    .orderBy(Product.name)
    .thenBy(Product.price, SortOrder.ASCENDING);
List<Product> products = demoService.getProducts(query);
val query = DataQuery()
    .filter(Product.name.contains("DVD"))
    .order(Product.name)
    .thenBy(Product.price, SortOrder.ASCENDING)
val products = demoService.getProducts(query)

Query an Entity to Get Data Including a Nested Entity and Its Association

GET OData.svc/Suppliers?$expand=Products,Products/ProductDetail&$orderby=Name HTTP/1.1
DataQuery query = new DataQuery()
//Include products from each supplier
.expand(Supplier.products)
        .expand(Supplier.products.path(Product.productDetail))
.orderBy(Supplier.name);
List<Supplier> suppliers = demoService.getSuppliers(query);
val query = DataQuery()
//Include products from each supplier
.expand(Supplier.products)
        .expand(Supplier.products.path(Product.productDetail))
.orderBy(Supplier.name);
val suppliers = demoService.getSuppliers(query)

Query to Retrieve an Entity Set Including Multiple Nested Entities

GET OData.svc/Products?$expand=Supplier,Categories HTTP/1.1
DataQuery query = new DataQuery().expand(Product.supplier, Product.categories);
List<Product> products = demoService.getProducts(query);
val query = DataQuery().expand(Product.supplier, Product.categories)
val products = demoService.getProducts(query)

Query Using a Logical Operator (Such as AND/OR)

GET OData.svc/Products?$filter=(substringof('DVD',Name) or substringof('LCD',Name)) HTTP/1.1
DataQuery query = new DataQuery()
.filter(Product.name.contains("DVD")
.or(Product.name.contains("LCD")));
List<Product> products = demoService.getProducts(query);
val query = DataQuery()
.filter(Product.name.contains("DVD")
.or(Product.name.contains("LCD")))
val products = demoService.getProducts(query)

Query Using a Binary Operator

GET OData.svc/Products?$filter=((substringof(‘DVD’,Name) or substringof(‘LCD’,Name)) and (Price lt 9.99e%2B1D)) HTTP/1.1
DataQuery quey = new DataQuery()
.filter(Product.name.contains("DVD").or(Product.name.contains("LCD"))
.and(Product.price.lessThan(99.9)));
List<Product> products = demoService.getProducts(query);
val query = DataQuery()
.filter(Product.name.contains("DVD").or(Product.name.contains("LCD"))
    .and(Product.price.lessThan(99.9)))
val products = demoService.getProducts(query)

Query to Fetch Selected Properties of an Entity

GET OData.svc/Products?$select=Name,Categories,Price&$expand=Categories&$filter=substringof('DVD',Name) HTTP/1.1
DataQuery query = new DataQuery()
    .filter(Product.name.contains("DVD"))
    .expand(Product.categories)
    .select(Product.name, Product.categories, Product.price);
List<Product> dvds = demoService.getProducts(query); //only name, categories, and price hold values
val query = DataQuery()
    .filter(Product.name.contains("DVD"))
    .expand(Product.categories)
    .select(Product.name, Product.categories, Product.price)
val dvds = demoService.getProducts(query) //only name, categories, and price hold values

Get to Get Count Matching the Condition

GET OData.svc/Products/$count?$filter=(substringof('DVD',Name) or substringof('LCD',Name)) HTTP/1.1
// Note use of from() to specify the entity set since we are using generic executeQuery() method
DataQuery query = new DataQuery()
    .count()
    .from(DemoServiceMetadata.EntitySets.products)
    .filter(Product.name.contains("DVD").or(Product.name.contains("LCD")));
long count = demoService.executeQuery(query).getCount();

// Set count only indicator to false to execute query to get the actual data
query.setCountOnly(false);
List<Product> products = demoService.getProducts(query);
// Note use of from() to specify the entity set since we are using generic executeQuery() method
val query = DataQuery()
    .count()
    .from(DemoServiceMetadata.EntitySets.products)
    .filter(Product.name.contains("DVD").or(Product.name.contains("LCD")))
val count = demoService.executeQuery(query).getCount()

// Set count only indicator to false to execute query to get the actual data
query.countOnly = false
val products = demoService.getProducts(query)

Main/Detail Queries

OData Request:

GET OData.svc/Suppliers?$select=ID,Name&$orderby=Name desc HTTP/1.1
GET OData.svc/Suppliers(1)/Products HTTP/1.1
DataQuery getSuppliers = new DataQuery()
    .select(Supplier.id, Supplier.name)
.orderBy(Supplier.name, SortOrder.DESCENDING);
List<Supplier> suppliers = demoService.getSuppliers(getSuppliers); //OData #1
Supplier supplier = suppliers.get(0);
DataQuery queryForLoad = new DataQuery().expand(Supplier.products);
demoService.loadEntity(supplier, queryForLoad); //OData #2
val query = DataQuery()
    .select(Supplier.id, Supplier.name)
.orderBy(Supplier.name, SortOrder.DESCENDING)
val suppliers = demoService.getSuppliers(query) //OData #1
val supplier = suppliers.get(0)
val queryForLoad = DataQuery().expand(Supplier.products)
demoService.loadEntity(supplier, queryForLoad) //OData #2

Get Paged Results

Note

Server may ignore page size in odata.maxpagesize preference

GET OData.svc/Suppliers HTTP/1.1
// Backend OData service must support paging
DataQuery pagedQuery = new DataQuery()
.from(DemoServiceMetadata.EntitySets.suppliers)
.page(10); // maximum page size of 10
do {
QueryResult result = demoService.executeQuery(pagedQuery);
        List<Supplier> suppliersPage = Supplier.list(result.getEntityList());
        pagedQuery = result.getNextQuery();
} while (pagedQuery.getUrl() != null);
// Backend OData service must support paging
var pagedQuery = DataQuery()
.from(DemoServiceMetadata.EntitySets.suppliers)
.page(10) // maximum page size of 10
do {
val result = demoService.executeQuery(pagedQuery)
    val suppliers = Supplier.list(result.entityList)
    pagedQuery = result.nextQuery
} while (pagedQuery.url != null)

Query Using a Filter on a GUID Attribute

GET OData.svc/Advertisements(guid'F89DEE73-AF9F-4CD4-B330-DB93C25FF3C7') HTTP/1.1
GUID guid = GUID.fromString("f89dee73-af9f-4cd4-b330-db93c25ff3c7");
DataQuery query = new DataQuery().withKey(Advertisement.key(GuidValue.of(guid)));
List<Advertisement> advertisements = demoService.getAdvertisements(query);
val guid = GUID.fromString("f89dee73-af9f-4cd4-b330-db93c25ff3c7")
val query = DataQuery().withKey(Advertisement.key(GuidValue.of(guid)))
val advertisements = demoService.getAdvertisements(query)

Create a New Entity

POST OData.svc/Products HTTP/1.1
//Set properties of the new entity object
Product newProduct = new Product();
newProduct.setId(id);
newProduct.setName(name);
newProduct.setDescription(desc);
newProduct.setRating(rating);
newProduct.setPrice(price);
newProduct.setReleaseDate(GlobalDateTime.of(1996, 1, 29, 8, 0, 0));//Jan-1-1996 08:00:00
demoService.createEntity(newProduct);
//Set properties of the new entity object
val newProduct = Product()
newProduct.id = id
newProduct.name = name
newProduct.description = desc
newProduct.rating = rating
newProduct.price = 39.99
newProduct.releaseDate = GlobalDateTime.of(1996, 1, 29, 8, 0, 0)) //Jan-1-1996 08:00:00
demoService.createEntity(newProduct)

Update an Existing Entity Object (MERGE/REPLACE Semantics)

Via MERGE:

MERGE OData.svc/Products(1000) HTTP/1.1

Via POST:

POST OData.svc/Products(1000) HTTP/1.1
X-HTTP-Method: Merge
newProduct.setDiscontinuedDate(GlobalDateTime.now());
RequestOptions ro = new RequestOptions();
ro.setUpdateMode(UpdateMode.MERGE);//default, REPLACE use is highly discouraged
demoService.updateEntity(newProduct, new HttpHeaders(), ro);
newProduct.discontinuedDate = GlobalDateTime.now()
RequestOptions ro = RequestOptions()
ro.setUpdateMode(UpdateMode.MERGE) //default, REPLACE use is highly discouraged
demoService.updateEntity(newProduct, HttpHeaders(), ro)

Delete an Entity

DELETE OData.svc/Products(...) HTTP/1.1
DataQuery query = new DataQuery()
.filter(Product.name.contains("DVD"));
List<Product> products = demoService.getProducts(query);
for (Product product: products) {
    demoService.deleteEntity(product);
}
val query = DataQuery().filter(Product.name.contains("DVD"))
val products = demoService.getProducts(query)
for (product in products) {
    demoService.deleteEntity(product)
}

Delete Using DataQuery()

Batch will contain all products to be deleted, each with its own DELETE request

GET OData.svc/Products?$filter=substringof('DVD',Name) HTTP/1.1
POST OData.svc/$batch HTTP/1.1
// Must use "from()" since we are using deleteByQuery()
DataQuery query = new DataQuery()
.from(DemoServiceMetadata.EntitySets.products)
.filter(Product.name.contains("DVD"));
demoService.deleteByQuery(query);
val query = DataQuery()
    .filter(Product.name.contains("DVD"))
.from(DemoServiceMetadata.EntitySets.products)
demoService.deleteByQuery(query)

Create an Entity and Associate with an Existing Entity

POST OData.svc/Suppliers(1)/Products HTTP/1.1
// Load supplier to be associated with
Supplier supplier = new Supplier();
supplier.setId(1);
demoService.loadEntity(supplier);
Product newProduct = new Product();
newProduct.setId(1001);
newProduct.setName("Notebook");
demoService.createRelatedEntity(newProduct, supplier, Supplier.products);
// Load supplier to be associated with
val supplier = Supplier()
supplier.id = 1
demoService.loadEntity(supplier)
val newProduct = Product()
newProduct.id = 1001
newProduct.name = "Notebook"
demoService.createRelatedEntity(newProduct, supplier, Supplier.products)

Deep Insert

POST OData.svc/Products HTTP/1.1
/**
** Send type info for Category and Supplier (required by this odata service)
** Usage of the option requires that odata service can handle the type info or else
** you may see some unexpected failure.
**/
provider.getServiceOptions().setRequiresType(true);
Category category = new Category();
category.setName("Electronics");
category.setId(8802);
Supplier supplier = new Supplier();
supplier.setName("Friendly");
supplier.setId(9902);
Address addr = new Address();
addr.setCity("Dublin");
addr.setCountry("USA");
addr.setState("CA");
addr.setZipCode("94568");
supplier.setAddress(addr);
List<Category> catList = new ArrayList<Category>();
catList.add(category);
newProduct.setCategories(catList);
newProduct.setSupplier(supplier);
demoService.createEntity(newProduct);
provider.serviceOptions.requiresType = true
val category = Category()
category.name = "Electronics"
category.id = 8802
val supplier = Supplier()
supplier.name = "Friendly"
supplier.id = 9902
val addr = Address()
addr.city = "Dublin"
addr.country = "USA"
addr.state = "CA"
addr.zipCode = "94568"
supplier.address = addr
val categories = ArrayList<Category>()
categories.add(category)
newProduct.categories = categories
newProduct.supplier = supplier
demoService.createEntity(newProduct)

Create a Media Entity (hasStream=true) with Binary Content

PUT media/Images HTTP/1.1
// Image Entity is stream enabled; hasStream=true
Image image = new Image();
image.setLabel("my photo");
InputStream is = this.getClass().getClassLoader().getResourceAsStream("testImage.png");
ByteStream newContent = ByteStream.fromInput(is);
newContent.setMediaType("image/png");
mediaService.createMedia(image, newContent);
val image = Image()
image.label = "my photo"
val is = this.class.classLoader.getResourceAsStream("testImage.png")
val newContent = ByteStream.fromInput(is)
newContent.mediaType = "image/png"
mediaService.createMedia(image, newContent)

Upload Binary Content to an Existing Media Entity (hasStream=true)

PUT media/Images(id)/$value HTTP/1.1
DataQuery query = new DataQuery().filter(Image.label.contains("Media"));
List<Image> images = mediaServices.getImages(query);
Image image = images.get(0);
InputStream is = this.getClass().getClassLoader().getResourceAsStream("testImage.png");
ByteStream newContent = ByteStream.fromInput(is);
newContent.setMediaType("image/png");
mediaService.uploadMedia(image, newContent);
val query = DataQuery().filter(Image.label.contains("Media"))
val images = mediaService.getImages(query)
val image = images.get(0)
val is = this.class.classLoader.getResourceAsStream("testImage.png")
val newContent = ByteStream.fromInput(is)
newContent.mediaType = "image/png"
mediaService.uploadMedia(image, newContent)

Serialize Entity Object to Cache

// Initialize cache
SecureStoreCache<String> categoryCache = new SecureStoreCache(context, 32, "categorycache");
categoryCache.open(myEncryptionKey);

Category category = new Category();
category.setId(ID);
service.loadEntity(newCategory);
// Build json representation from entity object
String jsonString = com.sap.cloud.mobile.odata.ToJSON.entity(category);
// Store json in cache
categoryCache.put(ID, jsonString);
// Initialize cache
val categoryCache = SecureStoreCache(context, 32, "categorycache")
categoryCache.open(myEncryptionKey)

val category = Category();
category.id = id
service.loadEntity(newCategory)
// Build json representation from entity object
val jsonString = com.sap.cloud.mobile.odata.ToJSON.entity(category)
// Store json in cache
categoryCache.put(id, jsonString)

Deserialize Entity Object From Cache

// Read entity json representation from cache
String jsonString = categoryCache.get(id);
// Build entity object from json representation
DataQuery query = com.sap.cloud.mobile.odata.FromJSON.entity(jsonString);
Category category = (Category) demoService.getCategory(query);
// Remove from cache if no longer needed
categoryCache.remove(id);
// Read entity json representation from cache
val jsonString = categoryCache.get(id)
// Build entity object from json representation
val query = com.sap.cloud.mobile.odata.FromJSON.entity(jsonString)
val category = demoService.getCategory(query)
// Remove from cache if no longer needed
categoryCache.remove(id)

Serialize Entity List Object to Cache

// Initialize cache
SecureStoreCache<String> entityListCache = new SecureStoreCache(context, 32, "entitylistcache");
entityListCache.open(myEncryptionKey);

List<Category> categories = demoService.getCategories();
// Build json representation from entity list object
String jsonString = com.sap.cloud.mobile.odata.ToJSON.entityList(categories);
// Store json in cache
entityListCache.put("categories", jsonString);
// Initialize cache
val entityListCache = SecureStoreCache(context, 32, "entitylistcache")
entityListCache.open(myEncryptionKey)

val categories = demoService.categories
// Build json representation from entity list object
String jsonString = com.sap.cloud.mobile.odata.ToJSON.entityList(categories)
// Store json in cache
entityListCache.put("categories", jsonString)

Deserialize Entity List Object From Cache

// Read entity list json representation from cache
String jsonString = entityListCache.get("categories");
// Build entity list object from json representation
DataQuery query = com.sap.cloud.mobile.odata.FromJSON.entityList(jsonString);
List<Category> categories = demoService.getCategories(query);
// Remove from cache if no longer needed
entityListCache.remove("categories");
// Read entity list json representation from cache
val jsonString = entityListCache.get("categories")
// Build entity list object from json representation
val query = com.sap.cloud.mobile.odata.FromJSON.entityList(jsonString)
val categories = demoService.getCategories(query)
// Remove from cache if no longer needed
entityListCache.remove("categories")

Last update: November 18, 2021