Several years ago, there was a set of End to End tutorials published in SCN that showcased developing applications on SAP HANA Cloud Platform.
The Enterprise Sales Procurement Model (ESPM) application was a reference implementation around a webshop scenario that educates on building applications with technologies like SAPUI5, OData etc., leveraging the Java runtime on SAP HANA Cloud Platform. The application demonstrated the consumption of different platform services like Persistence Service etc.
Today, SAP HANA Cloud Platform offers a rich set of Capabilities and Services. Going hand in hand, ESPM application also needed to showcase the consumption of some these new set of services and capabilities.
We are glad to now offer a newer updated ESPM application that showcases a subset of capabilities and services offered by SAP HANA Cloud Platform:
- SAP Jam
- Document Service
- Authorization Management
From a technology point of view, the ESPM application showcases the following technologies:
- SAPUI5
- OData
- JPA for persistence
- SAP HANA DB
Below is the architecture diagram of the ESPM application.
The front end of the ESPM application is also now updated based on the newer blue crystal theme of SAPUI5. Below is a snapshot of the webshop application home page.
ESPM Source code and documentation
The above repository has multiple branches and some of those branches are for the openSAP course “Developing Java-Based Apps on SAP HANA Cloud Platform”.
The new openSAP course Developing Java-Based Apps on SAP HANA Cloud Platform started just a few days back on Wednesday, September 7th 2016, explains how to develop Java-based apps on SAP HANA Cloud Platform using the newly updated ESPM application. The openSAP Course guide on SCN for your reference.
During the course of the above openSAP course, you will learn SAP HANA Cloud Platform capabilities and services with ESPM application.
Hope you will find the ESPM version 2.0 useful. Do post in your comments and feedback. Happy coding!
Hello Krishna,
a quick question concerning the xml binding of the odata: when I try to consume the odata service in a standardlist via the items aggreation the browser console shows this error:
Log-dbg.js:456 2021-02-02 13:47:42.310324 HTTP request failed (500 Internal Server Error): {"error":{"code":null,"message":{"lang":"en","value":"Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.6.4.v20160829-44060b6): org.eclipse.persistence.exceptions.DatabaseException\nInternal Exception: java.sql.SQLException: Borrow prepareStatement from pool failed\nError Code: 0\nCall: SELECT * FROM (SELECT * FROM (SELECT EL_TEMP.*, ROWNUMBER() OVER() AS EL_ROWNM FROM (SELECT PRODUCT_ID AS a1, CATEGORY AS a2, CATEGORY_NAME AS a3, CURRENCY_CODE AS a4, DIMENSION_DEPTH AS a5, DIMENSION_HEIGHT AS a6, DIMENSION_UNIT AS a7, DIMENSION_WIDTH AS a8, LONG_DESCRIPTION AS a9, NAME AS a10, PICTURE_URL AS a11, PRICE AS a12, QUANTITY_UNIT AS a13, SHORT_DESCRIPTION AS a14, SUPPLIER_ID AS a15, WEIGHT AS a16, WEIGHT_UNIT AS a17, SUPPLIER_SUPPLIER_ID AS a18 FROM ESPM_PRODUCT ORDER BY PRODUCT_ID) AS EL_TEMP) AS EL_TEMP2 WHERE EL_ROWNM <= ?) AS EL_TEMP3 WHERE EL_ROWNM > ?\n\tbind => [2 parameters bound]\nQuery: ReadAllQuery(referenceClass=Product sql=\"SELECT * FROM (SELECT * FROM (SELECT EL_TEMP.*, ROWNUMBER() OVER() AS EL_ROWNM FROM (SELECT PRODUCT_ID AS a1, CATEGORY AS a2, CATEGORY_NAME AS a3, CURRENCY_CODE AS a4, DIMENSION_DEPTH AS a5, DIMENSION_HEIGHT AS a6, DIMENSION_UNIT AS a7, DIMENSION_WIDTH AS a8, LONG_DESCRIPTION AS a9, NAME AS a10, PICTURE_URL AS a11, PRICE AS a12, QUANTITY_UNIT AS a13, SHORT_DESCRIPTION AS a14, SUPPLIER_ID AS a15, WEIGHT AS a16, WEIGHT_UNIT AS a17, SUPPLIER_SUPPLIER_ID AS a18 FROM ESPM_PRODUCT ORDER BY PRODUCT_ID) AS EL_TEMP) AS EL_TEMP2 WHERE EL_ROWNM <= ?) AS EL_TEMP3 WHERE EL_ROWNM > ?\")"}}} - sap.ui.model.odata.v2.ODataModel
f @ Log-dbg.js:456
L.error @ Log-dbg.js:232
J._handleError @ ODataModel-dbg.js:4389
J._processError @ ODataModel-dbg.js:4085
X @ ODataModel-dbg.js:3275
Y @ ODataModel-dbg.js:3347
W @ ODataModel-dbg.js:3051
(anonymous) @ ODataModel-dbg.js:6618
eval @ datajs.js?eval:17
p9 @ datajs.js?eval:17
XMLHttpRequest.send (async)
request @ datajs.js?eval:17
E2 @ datajs.js?eval:17
o.request @ datajs.js?eval:17
J._request @ ODataModel-dbg.js:6624
_ @ ODataModel-dbg.js:3135
(anonymous) @ ODataModel-dbg.js:3094
Promise.then (async)
Z @ ODataModel-dbg.js:3089
J._submitRequest @ ODataModel-dbg.js:3155
J._submitBatchRequest @ ODataModel-dbg.js:3389
(anonymous) @ ODataModel-dbg.js:3808
e @ each-dbg.js:61
J._processRequestQueue @ ODataModel-dbg.js:3758
(anonymous) @ ODataModel-dbg.js:3864
Promise.then (async)
(anonymous) @ ODataModel-dbg.js:3863
Promise.then (async)
J._processRequestQueueAsync @ ODataModel-dbg.js:3862
(anonymous) @ ODataModel-dbg.js:4618
Promise.then (async)
J._processRequest @ ODataModel-dbg.js:4610
J.read @ ODataModel-dbg.js:5307
n._getLength @ ODataListBinding-dbg.js:808
n.getContexts @ ODataListBinding-dbg.js:169
o.refreshAggregation @ ManagedObject-dbg.js:4116
t.refreshItems @ ListBase-dbg.js:594
A.refresh @ ManagedObjectMetadata-dbg.js:392
r @ ManagedObject-dbg.js:3833
b.fireEvent @ EventProvider-dbg.js:247
n._fireRefresh @ ODataListBinding-dbg.js:896
n.initialize @ ODataListBinding-dbg.js:978
o._bindAggregation @ ManagedObject-dbg.js:3876
t._bindAggregation @ ListBase-dbg.js:700
o.updateBindings @ ManagedObject-dbg.js:4271
o._propagateProperties @ ManagedObject-dbg.js:4740
o.propagateProperties @ ManagedObject-dbg.js:4721
o._propagateProperties @ ManagedObject-dbg.js:4743
o.propagateProperties @ ManagedObject-dbg.js:4721
o._propagateProperties @ ManagedObject-dbg.js:4743
o.propagateProperties @ ManagedObject-dbg.js:4715
o.setParent @ ManagedObject-dbg.js:2624
o.addAggregation @ ManagedObject-dbg.js:2160
(anonymous) @ XMLTemplateProcessor-dbg.js:684
Promise.then (async)
(anonymous) @ XMLTemplateProcessor-dbg.js:657
(anonymous) @ SyncPromise-dbg.js:309
c @ SyncPromise-dbg.js:60
S @ SyncPromise-dbg.js:225
S.then @ SyncPromise-dbg.js:308
Z @ XMLTemplateProcessor-dbg.js:654
$ @ XMLTemplateProcessor-dbg.js:725
x @ XMLTemplateProcessor-dbg.js:553
t.parseTemplatePromise @ XMLTemplateProcessor-dbg.js:321
m.onControllerConnected @ XMLView-dbg.js:655
F @ View-dbg.js:492
r @ Component-dbg.js:203
s.runAsOwner @ Component-dbg.js:613
P @ View-dbg.js:476
(anonymous) @ View-dbg.js:504
Promise.then (async)
g._initCompositeSupport @ View-dbg.js:503
(anonymous) @ ManagedObject-dbg.js:528
constructor @ ManagedObject-dbg.js:552
constructor @ Element-dbg.js:200
constructor @ Control-dbg.js:181
f @ Metadata-dbg.js:453
f @ Metadata-dbg.js:453
w @ View-dbg.js:1153
v @ View-dbg.js:1117
c.createContent @ UIComponent-dbg.js:584
(anonymous) @ UIComponent-dbg.js:329
o.runWithPreprocessors @ ManagedObject-dbg.js:1015
(anonymous) @ UIComponent-dbg.js:328
r @ Component-dbg.js:203
s.runAsOwner @ Component-dbg.js:613
c.init @ UIComponent-dbg.js:327
init @ Component.js:21
(anonymous) @ ManagedObject-dbg.js:533
constructor @ ManagedObject-dbg.js:552
constructor @ Component-dbg.js:304
constructor @ UIComponent-dbg.js:86
f @ Metadata-dbg.js:453
l1 @ Component-dbg.js:2634
D @ Component-dbg.js:2219
(anonymous) @ Component-dbg.js:2274
r @ Component-dbg.js:203
(anonymous) @ Component-dbg.js:2273
Promise.then (async)
z @ Component-dbg.js:2272
s.create @ Component-dbg.js:2079
i @ Component-dbg.js:1224
s._createComponent @ Component-dbg.js:1235
e._createComponent @ ComponentContainer-dbg.js:354
e.onBeforeRendering @ ComponentContainer-dbg.js:373
d._handleEvent @ Element-dbg.js:336
$ @ RenderManager-dbg.js:783
R.renderControl @ RenderManager-dbg.js:904
R.render @ RenderManager-dbg.js:1286
U.rerender @ UIArea-dbg.js:650
Y.renderPendingUIUpdates @ Core-dbg.js:2813
setTimeout (async)
Y.addInvalidatedUIArea @ Core-dbg.js:2751
U.addInvalidatedControl @ UIArea-dbg.js:541
U.invalidate @ UIArea-dbg.js:520
o.setParent @ ManagedObject-dbg.js:2635
o.addAggregation @ ManagedObject-dbg.js:2160
U.addContent @ UIArea-dbg.js:378
(anonymous) @ Interface-dbg.js:57
c.placeAt @ Control-dbg.js:669
e.run @ ComponentSupport-dbg.js:125
(anonymous) @ ComponentSupport-dbg.js:224
(anonymous) @ ui5loader-dbg.js:1829
Promise.then (async)
requireAll @ ui5loader-dbg.js:1747
executeModuleDefinition @ ui5loader-dbg.js:1803
(anonymous) @ ui5loader-dbg.js:1221
ModuleDefinitionQueue.process @ ui5loader-dbg.js:1219
execModule @ ui5loader-dbg.js:1671
requireModule @ ui5loader-dbg.js:1463
requireAll @ ui5loader-dbg.js:1737
r @ ui5loader-dbg.js:1993
setTimeout (async)
Y._executeOnInit @ Core-dbg.js:1287
Y._executeInitialization @ Core-dbg.js:1398
Y.init @ Core-dbg.js:1226
(anonymous) @ Core-dbg.js:477
m @ Core-dbg.js:170
X.finishTask @ Core-dbg.js:164
(anonymous) @ Core-dbg.js:500
(anonymous) @ Core-dbg.js:892
Promise.then (async)
Y._boot @ Core-dbg.js:891
(anonymous) @ Core-dbg.js:499
m @ Core-dbg.js:170
X.finishTask @ Core-dbg.js:164
(anonymous) @ Core-dbg.js:574
Promise.then (async)
constructor @ Core-dbg.js:573
(anonymous) @ Core-dbg.js:4227
(anonymous) @ ui5loader-dbg.js:1829
requireAll @ ui5loader-dbg.js:1752
executeModuleDefinition @ ui5loader-dbg.js:1803
ui5Define @ ui5loader-dbg.js:1935
execModule @ ui5loader-dbg.js:1625
requireModule @ ui5loader-dbg.js:1463
requireSync @ ui5loader-dbg.js:2062
(anonymous) @ jquery-mobile-custom-dbg.js:2163
An direct access via odatamodel.read function works without any issues and I can bind it then via a local json model. but of course, a direct binding how we use it with abap gateway services would be easier. Do I miss something here? Or is it not possible at all with java odata services?
Here my example how I try it directly in the xml:
<List id="listSapDemo" headerText="Products" items="{path : '/Products'}">
<StandardListItem title="{Name}"/>
</List>
Kind regards,
Oliver