Skip to Content
Author's profile photo John Appleby

10 tips for SAP River developers

SAP River has been released as of SAP HANA SP7 in December, so I’ve had my hands on it for over a month now, and written a good pile of code. Thanks to the River team for supporting my… many… questions. I thought I’d give back with some developer tips for River.

1) Use (sometimes)

Even if you, like me, have an on-premise SAP HANA appliance with SAP River, you may find it useful to use The reason for this is that has a newer version of the interface and can often pick out errors in your code that HANA Studio may fail to do. Also, you can share your code with other people in the cloud, which can be handy.

If you don’t have a SAP HANA appliance loaded with SAP River, then is a great way to get started and build some apps!

2) Take time to design your schema

You will get every minute you take to design your schema back, ten times over, when you come to develop apps. There are a number of key things, but remember that River doesn’t support changing elements within entities when they have data – only adding of new entities:

– Think carefully about entities and the relationships between them

– Get the key, and required elements in the entities locked down

– Use the correct types, and reduce the length of them where possible (especially strings, which default to length 5000)

3) Never duplicate data

In the latest app I am building, there are a lot of time-based elements. For instance there is a person, who has a date of birth, an age (in decimal, integer, remainder and age band form). There are another 5 or so entities which also relate to time, and age (in 4 forms) is stored against each of those entities so you can get age at time of transaction.

With River, we need to store 1) date of birth and 2) date of transaction – all the other 20-30 copies are entirely redundant. Instead we calculate them on demand by using calculated elements:

element Age: Integer = sap.hana.util.dateTime.daysBetween(BirthDate,sap.hana.util.dateTime.currentUTCTimestamp())/365.25;

We can do age bands just as easily

element ageRange : Integer = select one rangeId from AgeRange where (age >= ageFrom && age < ageTo);

entity AgeRange {

     key rangeId: Integer;

     ageFrom: Integer;

     ageTo: Integer;


There is massive simplicity caused by never duplicating data – you never need to worry about whether an element is up to date. And even in my testing with large volumes of records, I get <200ms round trip times from the OData services from Chrome.

4) Use enumerated types to create the equivalent of foreign key restrictions

This is very handy – enumerated types are your friend! If you use them then they will restrict the entry criteria, which is very handy indeed.

element country: CountryCode;

type CountryCode: String(2) enum { US; CA; }

5) You can get the OData documentation in a browser

I don’t find that the OData browser works that well in HANA Studio – it works much better in a browser. Happily, you can go directly to it and bookmark your project, using the following syntax:


6) Keep an eye on the HANA Index Server Trace file

Sometimes your RDL will misbehave and the syntax checker in HANA Studio won’t pick it up. You get this dreaded message:


Internal error occurred, please check the logs / contact your Administrator.

When this happens, you can try using the version of the editor, or alternatively you can look at the HANA Index Server Trace. This will often give you a clue as to where the problem is.

I also recommend introducing new concepts slowly – for instance I built 10 views in a row yesterday, which all had the same problem, and troubleshooting the RDL was difficult until I removed 9 of them, corrected one, and duplicated my code 9 times.

7) Python is your friend!

I use Python to test all my RDL code – it is much better than Postman when it comes to the need to test and retest OData, plus you get the added advantage of being able to reload data quickly. I use Python either on my Mac, or when I need better performance, on the HANA server itself.

The HTTP Requests library is an excellent way to connect to River and test your code. It’s also a great way to do data loads because you get all the River syntax checking, which you don’t get if you load CSVs.

The only downside is that the current implementation of River only allows one record per OData call, which means that a large number of records can take some time to load! For higher-performance loads, I’ve been testing using HTTP Threads in Python to queue up data, and insert with up to 10 concurrent threads.

8) Use your River project for other stuff too

By default, your River project will have just one file – the RDL that contains all your code. However, I usually reuse the HANA repository workspace for all of my development artifacts – it is a handy dumping ground, to keep all your code in one place!

– Associated SQL for testing purposes

– Python files and associated CSV for loading data

– SAPUI5 artifacts

– Information views (Calculation Views)

9) Use GitHub to share your River repository workspace

This is a tip from Bluefin colleagues Brenton O’Callaghan and DJ Adams. Your River/HANA repository workspace will exist in whatever folder you put it in, and you can handily configure your River repository workspace to also be the location for a GitHub repository. Now you can share your River project with friends and co-developers in the cloud. At Bluefin we also use an on-premise Gitlab instance that Oliver Rogers built, which allows us to store more sensitive code in a safe place.

Final Words

I’m building a substantial and complex app in River in my spare time, and I’m very impressed by the increase in simplicity and reduction of storage cost that River provides. You store information only once, and then describe in clear English how it is represented.

Exposing complex data views is straightforward and you don’t need to worry about joins – they are all implicit in your entity association definition. It takes a while to get used to the entity modeling approach of River and I recommend that you take some time to read about Entity Relationship Modeling before you get started.

River was intended to be a reinvention of the programming paradigm and this first version is a move in that direction. With the anticipated full second release of River in Q2 of 2014, I think we will see significant progress, but there is more than enough in the first release to build complex business applications. I suggest you get started now.

Assigned Tags

      You must be Logged on to comment or reply to a post.
      Author's profile photo Fred Verheul
      Fred Verheul

      Excellent John,

      Thanks for giving back to the community ๐Ÿ™‚ . I just started exploring stuff on and I'm already impressed. I can certainly use your tips in the near future.

      Cheers, Fred

      Author's profile photo John Appleby
      John Appleby
      Blog Post Author

      Glad you enjoyed - I feel obliged to give back - the River team are putting up with a lot from me, much of which is caused by my ignorance. The least I can do is to explain some of my ignorance!

      Author's profile photo Krishna Tangudu
      Krishna Tangudu

      Excellent narration and great overview and tips John.. Always like the way you write the blogs.. such an inspiration.. i hope i can write blogs at this level one day and share it with community.....


      Krishna Tangudu

      Author's profile photo Stephen Johannes
      Stephen Johannes

      For those of us who rather not code but model, based on your experimentation do you see RDL being something that could be generated by a graphical modeling tool instead of having to create the data model definitions by hand?  I honestly like the concept, but think that having to define data models "manually" seems quite "incomplete".

      Take care,


      Author's profile photo John Appleby
      John Appleby
      Blog Post Author

      It's a good question and one that I believe the developer team is working on.

      The purpose of River is to redefine the development process and clearly the interface is a key part of that. This initial release doesn't bring any of that.

      Where we think it might go, is for the high level entity model definition to be graphical, with actions and some detailed elements being written in code. This means you could zoom in and out of the model to the level of detail that you want to work at.

      River is definitely incomplete - it is a Version 1, Early Adopters release. The SP08 release of HANA promises to bring a lot of interesting things.

      Author's profile photo Philip MUGGLESTONE
      Philip MUGGLESTONE

      Great blog John! Some superb advice there - and interesting ideas for future SAP HANA Academy videos ๐Ÿ˜‰

      Author's profile photo John Appleby
      John Appleby
      Blog Post Author

      Thanks mate. By the way I meant to say, you interchange HTTP Headers and Parameters in the River videos. It looks like River accepts them interchangeably but your video does it differently to the reference guide. Not sure if this matters for later versions.

      Author's profile photo Philip MUGGLESTONE
      Philip MUGGLESTONE

      Assume you refer to x-csrf-token? All the doc I've seen says this should be put in the HTTP headers - both for River and regular XS OData. If I used HTTP parameters for this in the videos it's a mistake… need to watch them again to check ๐Ÿ˜‰

      Author's profile photo Rama Shankar
      Rama Shankar

      Great Info - Thanks John! ๐Ÿ™‚

      Author's profile photo Former Member
      Former Member

      Great document!

      Just one question regarding tip 9: "By default, your River project will have just one file[...]"

      Is there a way that one application's entity can access another's entity?

      For example: I have an application (.rdl file) that contains an entity Person, and I have in another application an entity Author that I want to be associated with the Person entity from the first one. Is that possible in this first release of River?

      Author's profile photo John Appleby
      John Appleby
      Blog Post Author

      Interesting question, and probably Rafi Bryl and team can give a better view.

      For now, one River app has one RDL file; it looks like this will be probably be changed in the next version. You can build River views on top of entities/tables in other River projects, if you would like.

      Or, You can build multiple namespaces with different entities in them.

      Also, you can access other OData services, including River and non-River services, by using an action and a break-out to XSJS.

      So there are options and workarounds. I'm not sure if what you described is on the roadmap.

      Author's profile photo Yoram Hod
      Yoram Hod

      John Appleby  covered in his answer most of the integration option supported in the first release. Today you can consume existing tables from different schemas. However, you won’t be able to benefit from associations, that is using the dot notation on external table (Author.person).

      In our next release you will be able to do exactly what you described. Associate between river entity across river applications.      

      Author's profile photo Former Member
      Former Member

      excellent tips๏ผŒthanks for sharing!