Skip to Content

Enterprise Sales Procurement Model (ESPM) application – Version 2.0 released

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.

 

ESPM-Arch.jpg

 

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-UI.png

ESPM Source code and documentation

The source code and documentation of ESPM application is available on Github.
The hyperlink to the Github repository for ESPM is https://github.com/SAP/cloud-espm-v2

 

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! 

 

1 Comment
You must be Logged on to comment or reply to a post.
  • 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