Understanding Persistence Service


What is SAP Persistence Service? One of the simplest definition is that it forms a bridge between your relational database and ABAP Objects.

If you have any experiences in other programming languages, like Java or C#, then maybe you have heard about ORM (Object-Relational Mapping) frameworks. These ORM tools enable you to construct classes with attributes, and then the framework will automatically generate the corresponding database tables in your database, and represent the data like objects.

Unfortunately, SAP Persistence Service isn't capable to act completely like above, but it's still a good initiative from SAP, and I am really excited to see the further improvements.

So, I wouldn't say that SAP Persistence Service it's an ORM tool, instead let's consider it as a layer (data access) in our application architecture that enables us to work with our relational database as ABAP Objects.

Today, I am going to introduce you the SAP Persistence Service using the database table, called SCARR (Airline). We are going to create a Persistent Class for Airlines, and I will show you its usage on very simple examples to ensure that you understand it easily.

Components of Persistence Service

The SAP Persistence Service consists of global classes and interfaces. The upper four interfaces are shared between all persistent classes, and the lower three classes are specific, and automatically generated for each Persistent Class that we create.

The ZCL_OS_SCARR is our Persistent Class that we are going to create later in this tutorial. It has to implement the interface IF_OS_STATE, that ensures that you can access all of your persistent objects in the same way. This class has as many attributes and GET/SET methods as many field exists in its connected persistent structure (table, view, structure) generated by the Class Builder.

For each Persistent Class two agent classes are generated by the Class Builder, an abstract and a final.

The ZCA_OS_SCARR is one of our Agent classes, and it's responsible is to manage our ZCL_OS_SCARR Persistent Objects (actually all the SQL statements take place in this Agent class), it serves as a data repository.

The ZCB_OS_SCARR, the super class of the ZCA_OS_SCARR is also generated by the Class Builder, and implements the following interfaces: IF_OS_FACTORY, IF_OS_CA_PERSISTENCY, IF_OS_CA_INSTANCE.

Create Persistent Class

I think learning something is much more easy based on practical examples than talking about, so let's jump to our tutorial!

In SE24, in the Class Builder, let's create a new class with the name, ZCL_OS_SCARR (since it's going to be the persistent class of the database table, called SCARR), and choose the class type, Persistent Class.


After saving our new class, we can check what exactly Persistent Class means. It implements the interface, IF_OS_STATE (like I showed you above).


It is also friend of our abstract Agent class, ZCB_OS_SCARR.

Set Persistence Representation

As you got familiar the parts of our Persistent Class, now we should connect an ABAP Dictionary object to our persistent class somehow, so let's set its Persistence Mapping, by pushing the button, Persistence.

Assign Table

Our first task is to assign a table/view/structure to our class, let's choose the database table that consists of airlines, called SCARR.

Maintain Properties of Attributes

After assigning our table, the Class Builder loads its metadata into the lower block, called Tables/Fields. Here, our task is to double click on one of the fields in order to load it into the Maintain Area.

Add Attribute to Persistent Class

In the Maintain Area, we have the chance to modify the ID, description, visibility of a field individually. After finishing the maintenance of the given field, just simply let's press ENTER in order to assign it to our Persistent Class as an attribute.

After pressing ENTER, the given field appears under the our class as an attribute and loads the next field into the Maintain Area, where we perform the same workflow.

Here, I have to mention that you must assign all of the fields from a table (there is no excuse). If you don't need all of the fields from a table, then let's create a view on it in the ABAP Dictionary, and assign the view to your Persistent Class.

After applying the same workflow for each field, we get the following attributes under our class:

New Attributes

After saving the persistence mapping, we can go back to our class definition, where we can check the generated attributes, based on the mappings.

New GET/SET Methods

Besides the new attributes, we get generated GET and SET methods also. The CARRID only has GET method, since it's a Business Key in the SCARR table, it's only readable.

Activate Actor Classes

There is nothing left, than activating our class. Besides the persistent class, the Class Builder wants to activate the Actor classes also. So let's choose, Yes! That's it! Now, you have a Persistent Class, called ZCL_OS_SCARR that you can use in the system.

Get an Airline Object

For the sake of the simplicity, let me show you the basic usage of persistent objects in very simple examples. I'm going to show you two different operations, displaying and creating. Let's check first the reading operation.

In the core of the TRY-CATCH block, we ask a reference of our agent class and save it in the reference variable airline_agent, by querying the class attribute of the ZCA_OS_SCARR, called agent (ZCA_OS_SCARR follows the singleton pattern).

Then, we simply ask the agent to get a persistent from the database with the business key 'BA', and we save the receiving reference of the airline instance in the reference variable, called airline.

From now on, we have an initialized instance of the ZCL_OS_SCARR (data came from database), and we can call one of its GET/SET method, like GET_CARRNAME().

DATA airline_agent TYPE REF TO zca_os_scarr.
DATA airline       TYPE REF TO zcl_os_scarr.
DATA airline_name  TYPE        s_carrname.

    airline_agent = zca_os_scarr=>agent.
    airline = airline_agent->get_persistent( 'BA' ).

    airline_name = airline->get_carrname( ).
    WRITE: 'Name of the selected airline: ', airline_name.
  CATCH cx_os_object_not_found.
    " error handling comes here

It's very effective, and it's also reusable among different clients, like ABAP programs, ABAP classes, Function Modules, and so on.

Here you can check the result:

Create an Airline Object

The next example is about creating an airline object using our Persistent Class. We ask again a reference of our agent class in the same way as we did previously, and save it in the variable, airline_agent.

Then we ask the agent to create a persistent in the database with the following parameters: 'WA', 'Wizz Air', 'HUF', 'http://wizzair.com'.

At last, there is nothing left then commit our work, and as a result a new record appears in our table.

DATA airline_agent TYPE REF TO zca_os_scarr.
DATA airline       TYPE REF TO zcl_os_scarr.

    airline_agent = zca_os_scarr=>agent.
    airline = airline_agent->create_persistent(
      i_carrid   = 'WA'
      i_carrname = 'Wizz Air'
      i_currcode = 'HUF'
      i_url      = 'http://wizzair.com'

  CATCH cx_os_object_existing.
    " error handling comes here

Here you can check the result of the code above:


Using Persistent Classes, we are able to take a further step towards to get more transparent, and well separated classes, based on responsibilities, like Data layer, Data Access layer, Business Layer, Application Layer, UI Layer (today we dealt only with the first two layers).

Another benefit of implementing such a these classes is that they reusable, we only have to implement them once and reuse them as many times as we want.

So as I told you at the beginning, it's a good initiative from SAP, but still there are some missing features from this great tool.

I'm really glad to see initiatives from SAP like this, because it means our ABAP language evolves, and some day, we can write such a nice clean ABAP codes that we can write today, for example in C#.

blog comments powered by Disqus