Skip to content

Querying and Modifying Data Using Proxy Classes

Get All Entities of an Entity Set

OData Request: GET .../OData.svc/Products

1
List<Product> products = demoService.getProducts();
1
val products = demoService.products

Get a Specific Entity via its Key

OData Request: GET .../OData.svc/Products(8)

1
2
3
4
5
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”));
1
2
val query = DataQuery().withKey(Product.key(8))
val product = demoService.getProduct(query)

Load an Entity

OData Request: GET .../OData.svc/Products(8)

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

1
2
3
Product product = new Product();
product.setId(8);
demoService.loadEntity(product); // product will hold the returned entity
1
2
3
val product = Product()
product.Id = 8
eventService.loadEntity(product)

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

OData Request: GET .../OData.svc/Products?$select=ID

1
2
DataQuery query = new DataQuery().selectKey();
List<Product> products = demoService.getProducts(query);
1
2
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.

OData Request: GET .../OData.svc/Products?$filter=substringof('DVD',Name)&$orderby=Name,Price

1
2
3
4
5
DataQuery query = new DataQuery()
    .filter(Product.name.contains("DVD"))
    .orderBy(Product.name)
    .thenBy(Product.price, SortOrder.ASCENDING);
List<Product> products = demoService.getProducts(query);
1
2
3
4
5
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

OData Request: GET .../OData.svc/Suppliers?$expand=Products,Products/ProductDetail&$orderby=Name

1
2
3
4
5
6
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);
1
2
3
4
5
6
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

OData Request: GET .../OData.svc/Products?$expand=Supplier,Categories

1
2
DataQuery query = new DataQuery().expand(Product.supplier, Product.categories);
List<Product> products = demoService.getProducts(query);
1
2
val query = DataQuery().expand(Product.supplier, Product.categories)
val products = demoService.getProducts(query)

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

OData Request: GET .../OData.svc/Products?$filter=(substringof('DVD',Name) or substringof('LCD',Name))

1
2
3
4
DataQuery query = new DataQuery()
    .filter(Product.name.contains("DVD")
        .or(Product.name.contains("LCD")));
List<Product> products = demoService.getProducts(query);
1
2
3
4
val query = DataQuery()
    .filter(Product.name.contains("DVD")
        .or(Product.name.contains("LCD")))
val products = demoService.getProducts(query)

Query Using a Binary Operator

OData Request: GET .../OData.svc/Products?$filter=((substringof(‘DVD’,Name) or substringof(‘LCD’,Name)) and (Price lt 9.99e%2B1D))

1
2
3
4
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);
1
2
3
4
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

OData Request: GET .../OData.svc/Products?$select=Name,Categories,Price&$expand=Categories&$filter=substringof('DVD',Name)

1
2
3
4
5
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
1
2
3
4
5
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

OData Request: GET .../OData.svc/Products/$count?$filter=(substringof('DVD',Name) or substringof('LCD',Name))

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// 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);
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// 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)

Master/Detail Queries

OData Request:

  1. Master query: GET .../OData.svc/Suppliers?$select=ID,Name&$orderby=Name desc
  2. Detail query: GET .../OData.svc/Suppliers(1)/Products
1
2
3
4
5
6
7
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
1
2
3
4
5
6
7
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

OData Request: GET .../OData.svc/Suppliers

Server may ignore page size in odata.maxpagesize preference

1
2
3
4
5
6
7
8
9
// 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);
1
2
3
4
5
6
7
8
9
// 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

OData Request: GET .../OData.svc/Advertisements(guid'F89DEE73-AF9F-4CD4-B330-DB93C25FF3C7')

1
2
3
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);
1
2
3
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

OData Request: POST.../OData.svc/Products

1
2
3
4
5
6
7
8
9
//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);
1
2
3
4
5
6
7
8
9
//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)

OData Request: POST (MERGE) .../OData.svc/Products(1000)

Http Header: "X-HTTP-Method": "MERGE"

1
2
3
4
newProduct.setDiscontinuedDate(GlobalDateTime.now());
RequestOptions ro = new RequestOptions();
ro.setUpdateMode(UpdateMode.MERGE);//default, REPLACE use is highly discouraged
demoService.updateEntity(newProduct, new HttpHeaders(), ro);
1
2
3
4
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

OData Request: DELETE .../OData.svc/Products(x) ... OData Request: DELETE .../OData.svc/Products(y)

1
2
3
4
5
6
DataQuery query = new DataQuery()
    .filter(Product.name.contains("DVD"));
List<Product> products = demoService.getProducts(query);
for (Product product: products) {
    demoService.deleteEntity(product);
}
1
2
3
4
5
val query = DataQuery().filter(Product.name.contains("DVD"))
val products = demoService.getProducts(query)
for (product in products) {
    demoService.deleteEntity(product)
}

Delete Using DataQuery()

OData:

  1. OData Request: GET .../OData.svc/Products?$filter=substringof('DVD',Name)
  2. OData Request: POST .../OData.svc/$batch

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

1
2
3
4
5
// Must use "from()" since we are using deleteByQuery()
DataQuery query = new DataQuery()
    .from(DemoServiceMetadata.EntitySets.products)
    .filter(Product.name.contains("DVD"));
demoService.deleteByQuery(query);
1
2
3
4
val query = DataQuery()
    .filter(Product.name.contains("DVD"))
    .from(DemoServiceMetadata.EntitySets.products)
demoService.deleteByQuery(query)

Create an Entity and Associate with an Existing Entity

OData Request: POST .../OData.svc/Suppliers(1)/Products

1
2
3
4
5
6
7
8
// 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); 
1
2
3
4
5
6
7
8
// 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

OData Request: POST .../OData.svc/Products

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/** 
 ** 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);
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
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

OData Request: POST .../media/Images

1
2
3
4
5
6
7
// 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);
1
2
3
4
5
6
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)

OData Request: PUT .../media/Images()/$value

1
2
3
4
5
6
7
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);
1
2
3
4
5
6
7
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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// 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);
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// 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)

De-Serialize Entity Object from Cache

1
2
3
4
5
6
7
// 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);
1
2
3
4
5
6
7
// 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

1
2
3
4
5
6
7
8
9
// 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);
1
2
3
4
5
6
7
8
9
// 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)

De-Serialize Entity List Object from Cache

1
2
3
4
5
6
7
// 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");
1
2
3
4
5
6
7
// 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")