This is a test message to test the length of the message box.
ABAP RAP Complex entity
Created by Software-Heroes

RAP - Complex entity


Let's look at a RAP application with two entities and how they are connected. We mainly focus on the differences.

A while ago we looked at a simple entity and how to build it entirely on top of RAP. In this article, we'll take a look at what the differences are when building more than one entity into an application. If you want to know more about the structure of simple entities, it is best to start at the beginning of the series.



We had already looked closely at how to build a RAP application using an entity and what we need. In this small series, we will look at building complex applications by merging invoices and positions in one application. We will again work with the data model on our CDS series.


Data model

We want to bring the two entities invoice and item together into one app and make it editable, the data model looks like this:


We need the entity for material because the unit of measure is required and this is only available for the material. As always, we create an interface layer and put the consumption layer on top for the application.



The first adaptation already exists at the data modeling level. We need links between the entities because we later want to navigate from the invoices to the items and because these two objects belong together. Let's take a closer look at the two layers.



At the interface level, we connect the invoices to the positions. To do this, we create a "composition" from the root node in the direction of the position, the view looks like this:

@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Interface for ZBS_DMO_INVOICE'
define root view entity ZBS_R_RAPCInvoice
  as select from zbs_dmo_invoice
  composition [0..*] of ZBS_I_RAPCPosition as _Position
  key document as Document,
      doc_date as DocDate,
      doc_time as DocTime,
      partner  as Partner,


At the position level, we now have to create an "Association To Parent" to make it clear that there is an upward relationship here. The second association is for the entity we need for the data.

@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Interface for ZBS_DMO_POSITION'
define view entity ZBS_I_RAPCPosition
  as select from zbs_dmo_position
  association     to parent ZBS_R_RAPCInvoice as _Invoice  on $projection.Document = _Invoice.Document
  association [1] to ZBS_I_RAPCMaterial       as _Material on $projection.Material = _Material.Material
  key document            as Document,
  key pos_number          as PositionNumber,
      material            as Material,
      @Semantics.quantity.unitOfMeasure : 'Unit'
      quantity            as Quantity,
      _Material.StockUnit as Unit,
      price               as Price,
      currency            as Currency,




It looks similar at the consumption level, but here the relationships are defined differently. To do this, we add a "Redirect to Composition Child" in the root entity after the association.

@EndUserText.label: 'Consumption for ZBS_R_RAPCINVOICE'
@AccessControl.authorizationCheck: #NOT_REQUIRED
@Metadata.allowExtensions: true
define root view entity ZBS_C_RAPCInvoice
  provider contract transactional_query
  as projection on ZBS_R_RAPCInvoice as Invoice
  key Document,
      _Position : redirected to composition child ZBS_C_RAPCPosition


For the items we need a "Redirect To Parent", i.e. to the invoice. The relationships are used later in the service for navigating between the entities.

@EndUserText.label: 'Consumption for ZBS_I_RAPCPOSITION'
@AccessControl.authorizationCheck: #NOT_REQUIRED
@Metadata.allowExtensions: true
define view entity ZBS_C_RAPCPosition
  as projection on ZBS_I_RAPCPosition as Position
  key Document,
  key PositionNumber,
      _Invoice : redirected to parent ZBS_C_RAPCInvoice


Behavior definition

Now what about managing behavior implementation? Here you need two definitions, one for each entity. Special features to consider here would be:

  • The item is created via the association of the invoice and not directly via the item.
  • Associations are announced in the entities.
  • Blocking and authorizing on the data of the item is done via the invoice.
  • The behavior implementation can be implemented per entity or via a class in the head of the behavior definition.


The definition of behavior is as follows:

managed implementation in class zbp_bs_rapcinvoice unique;
strict ( 1 );

define behavior for ZBS_R_RAPCInvoice alias Invoice
persistent table zbs_dmo_invoice
lock master
authorization master ( instance )

  field ( readonly:update ) Document;

  association _Position { create; }
  mapping for zbs_dmo_invoice
      Document = document;
      Partner  = partner;
      DocDate  = doc_date;
      DocTime  = doc_time;

define behavior for ZBS_I_RAPCPosition alias Position
persistent table zbs_dmo_position
lock dependent by _Invoice
authorization dependent by _Invoice

  field ( readonly ) Document;
  field ( readonly:update ) PositionNumber;

  association _Invoice;
  mapping for zbs_dmo_position
      Document       = document;
      PositionNumber = pos_number;
      Material       = material;
      Price          = price;
      Quantity       = quantity;
      Currency       = currency;


However, you can best see how the associations are handled in the projection of the behavior definition:

strict ( 1 );

define behavior for ZBS_C_RAPCInvoice alias Invoice
  use create;
  use update;
  use delete;

  use association _Position { create; }

define behavior for ZBS_C_RAPCPosition alias Position
  use update;
  use delete;

  use association _Invoice;



The service definition and the service binding can then be created as usual, both entities should be given so that access is available for them. After creating the binding, the two entities should be visible, as well as the connections between them.



The application itself has no design, fields or restriction options. As before, you can use the Fiori Elements Preview to define a basic layout, at least to be able to test it once. A navigation to the positions is currently not possible, for this we first have to create the UI annotations.



As always, we have made the changes available in the GitHub repository. The customization commit created new objects in the ZBS_DEMO_RAP_COMPLEXE package if you don't want to search everything.



The structure of the application is similar to our simple application, but there are a few things to note, for example that the individual entities are linked to each other. As usual, you can find all changes in the GitHub repository.

Included topics:
RAPBTPComplex entity
Comments (0)

And further ...

Are you satisfied with the content of the article? We post new content in the ABAP area every Friday and irregularly in all other areas. Take a look at our tools and apps, we provide them free of charge.

RAP - Deep Action in OData v4

Category - ABAP

In this article we will look at actions with deep structures, how we can create them and pass data to an API endpoint.


BTP - Connect On-Premise (Consumption Model v2)

Category - ABAP

In this article we want to provide another update on the connection of on-premise systems and how this is done with a communication arrangement.


RAP - Show app count (Tile)

Category - ABAP

This example is about displaying a counter on the tile of a Fiori Elements application and how such a thing can be implemented.


RAP - Generator (Fiori)

Category - ABAP

In this article we will look at the more complex RAP generator as a Fiori Elements application and what advantages you have with it.


RAP - Generator (ADT)

Category - ABAP

Today, let's take a look at the RAP Generator, which is already integrated into ABAP Development Tools, and how you can use it to easily build new RAP apps.