A couple of months ago we started building an application on Hana Cloud Platform using JPA and we quickly ran into a gap.

Jonathan Jouret and I gave a presentation during SAP Teched 2015 and based on all the feedback we received, I decided to write a small blog to help our community. Actually, this would be a good project to work on with a wider community and hopefully we can contribute all to this project and make it stronger and managing more cases.

The gap:

In HCP, it is possible to use different databases such as SAP Hana DB, MaxDB or Sybase,,, it is great especially that we should not really care as we were using JPA as abstraction for our database operations.

However, as the development progressed, we were stuck as we wanted to see the content of the database and if possible even make some modifications. Although in Eclipse it is possible to see the content of the DB using the Administrator Console, it was limited to Hana DB only and a lot more tables than our entities were created (to manage the dependancies between the entities).

The solution we found:

To help us during the development, we really wanted to see what was happening in the database so we decided to build a small tool that has the following architecture.

In short, the application would use the following components:

– OpenUI5 that will manage the display of the database entities and content

– oData to fetch the list of entities, get the values from the DB and manipulate them (using Olingo 2.0)

– EclipseLink for the JPA management

Note that on our “production” system, we decided to have one HTML5 application (containing all the OpenUI5 code) and the few Java necessary classes. This is allowing us to reuse our HTML5 application with multiple JAVA applications just by changing the destination. However, to make it easier to share, we created a sample in one package.

The end result looks like:

In the following picture, you can see what the solution looks like… on the left side, we have the list of all our entities and on the right side (once an entity is chosen), the content of the database is displayed.

Capture 2015-11-01 at 11.08.37.png

By default, we use a “view mode” but the user can switch to edit more to create/delete and modify entities content.

The advantages of using this solution:

This little application helped us quite a lot as we were able to see at anytime the content of the database and modify it’s content however there are a few reasons why I liked using this solution rather than the Admin Console:

– The main reason was that we were using MaxDB and had no access to the content even using the admin console

– We build a link (so if an entity refers to an other one, you can just click on the link and the target entity will be displayed filtered on the data you clicked on)

– It respects authorisations and multi-tenancy

– It maintains the integrity of the database (if a parent is deleted, the children are deleted following the propagation).

Note that there are some hardcoded parts in the application regarding “description” columns, etc…

What do you need to do to make this work:

We wanted to make it as reusable as possible since we are working on multiple projects internally. So we made it very easy to be used. Note that if you want to test the app, you can just test it locally (in your eclipse) or deploy it on HCP as a Java application but if you want to make the best of the application, just follow these easy steps.

In your JAVA application:

I am assuming that your JPA database is already built and you are using EclipseLink (at least 2.5.1) as advised by SAP for all the HCP developments.

1/ You have to include the oLingo libraries in your project (I used Maven but you can simply download them from Apache).

2/ Create a service inheriting from the olingo class ODataJPAServiceFactory and override the constructor and initializeODataJPAContext


public class DatabaseService extends ODataJPAServiceFactory {
private EntityManagerFactory emf;
 private String persistenceUnitName = "[InsertYourPersistenceUnitNameHere]";
 @SuppressWarnings({ "rawtypes", "unchecked" })
  public DatabaseService() {
  try {
  InitialContext ctx = new InitialContext();
  DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/DefaultDB");
  Map properties = new HashMap();
  properties.put(PersistenceUnitProperties.NON_JTA_DATASOURCE, ds);
  properties.put("eclipselink.ddl-generation", "create-or-extend-tables");
  emf = Persistence.createEntityManagerFactory(persistenceUnitName, properties);
  } catch (NamingException e) {
  }
  }
 @Override
  public ODataJPAContext initializeODataJPAContext()
  throws ODataJPARuntimeException {
  ODataJPAContext oDataJPAContext = this.getODataJPAContext();
  try {
  oDataJPAContext.setEntityManagerFactory(emf);
  oDataJPAContext.setPersistenceUnitName(persistenceUnitName);
  return oDataJPAContext;
  } catch (Exception e) {
  throw new RuntimeException(e);
  }
  }
}




3/ Modify your web.xml file to add the class in the list of servlets available and add the name of your class you just created at step 2


<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://java.sun.com/xml/ns/javaee"
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
 id="WebApp_ID" version="3.0">
 <resource-ref>
  <res-ref-name>jdbc/DefaultDB</res-ref-name>
  <res-type>javax.sql.DataSource</res-type>
 </resource-ref>
 <servlet>
  <servlet-name>oDataAPI</servlet-name>
  <servlet-class>org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet</servlet-class>
  <init-param>
  <param-name>javax.ws.rs.Application</param-name>
  <param-value>org.apache.olingo.odata2.core.rest.app.ODataApplication</param-value>
  </init-param>
  <init-param>
  <param-name>org.apache.olingo.odata2.service.factory</param-name>
  <param-value>[Package of your Class].DatabaseService</param-value>
  </init-param>
 </servlet>
 <servlet-mapping>
  <servlet-name>oDataAPI</servlet-name>
  <url-pattern>/oDataAPI/*</url-pattern>
 </servlet-mapping>
</web-app>




In your HTML5 application:

Just copy all our files and change the destination DEV204 to the service you created in JAVA…

Let’s all program together:

Here is the link to our GIT if you want to make some enhancements, just feel free and most importantly share with everyone 🙂 Note that we dont take any responsibility for this code.

To report this post you need to login first.

1 Comment

You must be Logged on to comment or reply to a post.

  1. Daniel Schaefer

    Hello,

    nice description.I am on a similar scenario. UI5 Framework at the client side. OData REST requests and an underlying HANA Database with JPA Persistence.

    I have a question:

    After creating the EMF at the first run of the application how can u close this EMF? Usually u do this with emf.close(). But i cannot find a callback method which will be executed after stopping the app.

    thanks

    Daniel

    (0) 

Leave a Reply