Numbering during create and create by association in RAP

Estimated read time 19 min read

Introduction 

In SAP ABAP RESTful Application Programming Model (RAP), the concepts of Create and Create by Association are fundamental for managing data persistence in business objects.

Implementing numbering mechanisms during these operations is essential to ensure unique identifiers for newly created entities.

This blog explores strategies and best practices for numbering during the Create operation and Create by Association, highlighting how RAP supports these processes in both managed and unmanaged scenarios.

Basic Information About Numbering 

Numbering in RAP refers to the process of assigning unique values to the key fields of business entities during Create operations.

Types of Numbering 

Early Numbering:Primary key values are assigned immediately when a creation operation is initiated. This mechanism is triggered during the interaction phase. Types: Managed Early Numbering: The RAP framework automatically assigns a UUID (Universal Unique Identifier) to the key field during the create request. Applicable for key fields of type RAW (16) in managed scenarios. Unmanaged Early Numbering: Developers implement custom logic to assign key values during the creation operation. Use Cases: Suitable for scenarios requiring immediate key assignment, such as generating unique identifiers for new records upon clicking “Create.”   Late Numbering:Primary key values are assigned just before the data is saved to the database. Triggered during the save sequence phase. 

Implementation: 

Developers implement the ADJUST_NUMBERS method to handle late numbering. This method is invoked during the save sequence to assign key values. 

Scenario Example 

In this example, we have designed a scenario with two views: 

Hospital View (Root entity) Patient View (Child entity, dependent on Hospital View) 

The Hospital View is the root entity, and the Patient View is related to it via a composition relationship. The patient data cannot exist independently of the hospital data. 

Below are the CDS view definitions and behavior implementations for the scenario: 

 

Hospital View

 

@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: ‘Hospital interface view’
@Metadata.ignorePropagatedAnnotations: true
@ObjectModel.usageType:{
serviceQuality: #X,
sizeCategory: #S,
dataClass: #MIXED
}
define root view entity zismo_i_hospital
as select from zismo_dt_hosp
composition [1..*] of zismo_i_patient as _patient
{
@UI.facet: [{
label: ‘Hospital information’,
purpose: #STANDARD,
type: #IDENTIFICATION_REFERENCE,
position: 10
},
{ label : ‘Patient information’,
purpose: #STANDARD,
type: #LINEITEM_REFERENCE,
position: 20,
targetElement: ‘_patient’ } ]

@UI.lineItem: [{ position: 10, label: ‘Hospital Id’ }]
@UI.identification: [{ position: 10, label: ‘Hospital Id’ }]
key hospital_id as HospitalId,

@UI.lineItem: [{ position: 20, label: ‘Hospital name’ }]
@UI.identification: [{ position: 20, label: ‘Hospital name’ }]
hospital_name as HospitalName,

@UI.lineItem: [{ position: 30, label: ‘Hospital location’ }]
@UI.identification: [{ position: 30, label: ‘Hospital location’ }]
hospital_location as HospitalLocation,

@UI.lineItem: [{ position: 40, label: ‘No of doctors’ }]
@UI.identification: [{ position: 40, label: ‘No of doctors’ }]
no_of_doctors as NoOfDoctors,

@UI.lineItem: [{ position: 50, label: ‘No of rooms’ }]
@UI.identification: [{ position: 50, label: ‘No of rooms’ }]
no_of_rooms as NoOfRooms,
_patient
}

 

Patient View 

 

@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: ‘Patient interface view’
@Metadata.ignorePropagatedAnnotations: true
@ObjectModel.usageType:{
serviceQuality: #X,
sizeCategory: #S,
dataClass: #MIXED
}
define view entity zismo_i_patient
as select from zismo_dt_patient
association to parent zismo_i_hospital as _hospital on $projection.HospitalId = _hospital.HospitalId
{
@UI.facet: [{
purpose: #STANDARD,
type: #IDENTIFICATION_REFERENCE,
position: 10
}]

@UI.lineItem: [{ position: 10, label: ‘Hospital Id’ }]
@UI.identification: [{ position: 10, label: ‘Hospital Id’ }]
key hospital_id as HospitalId,

@UI.lineItem: [{ position: 20, label: ‘Patient Id’ }]
@UI.identification: [{ position: 20, label: ‘Patient Id’ }]
key patient_id as PatientId,

@UI.lineItem: [{ position: 30, label: ‘Patient name’ }]
@UI.identification: [{ position: 30, label: ‘Patient name’ }]
patient_name as PatientName,

@UI.lineItem: [{ position: 40, label: ‘Medical cause’ }]
@UI.identification: [{ position: 40, label: ‘Medical cause’ }]
medical_cause as MedicalCause,

@UI.lineItem: [{ position: 50, label: ‘Doctor assigned’ }]
@UI.identification: [{ position: 50, label: ‘Doctor assigned’ }]
doctor_assigned as DoctorAssigned,

@UI.lineItem: [{ position: 60, label: ‘Room no’ }]
@UI.identification: [{ position: 60, label: ‘Room no’ }]
room_no as RoomNo,

@UI.lineItem: [{ position: 70, label: ‘Payment status’ }]
@UI.identification: [{ position: 70, label: ‘Payment status’ }]
payment_status as PaymentStatus,
_hospital
}

 

To manage the functionality of the scenario, I have created a behavior definition for the root view (Hospital View).  

This behavior definition defines the operations and interactions that can be performed on the hospital entity and its associated patient entities. 

 

managed implementation in class zbp_ismo_i_hospital unique;
strict ( 2 );

define behavior for zismo_i_hospital alias hospital
persistent table zismo_dt_hosp
lock master
authorization master ( instance )
{
create;
update;
delete;

field ( readonly : update ) HospitalId;
association _patient { create; }

mapping for zismo_dt_hosp
{
HospitalId = hospital_id;
HospitalName = hospital_name;
HospitalLocation = hospital_location;
NoOfDoctors = no_of_doctors;
NoOfRooms = no_of_rooms;
}
}

define behavior for zismo_i_patient alias patient
persistent table zismo_dt_patient
lock dependent by _hospital
authorization dependent by _hospital
{
update;
delete;

field ( readonly ) HospitalId;
field ( readonly : update ) PatientId;
association _hospital;

mapping for zismo_dt_patient
{
HospitalId = hospital_id;
PatientId = patient_id;
PatientName = patient_name;
MedicalCause = medical_cause;
DoctorAssigned = doctor_assigned;
RoomNo = room_no;
PaymentStatus = payment_status;
}
}

 

Step by Step implementation 

Early numbering managed

Let’s start with parent entity, in our case hospital view 

For managed early numbering, ensure that the key field is of type SYSUUIDx16 (RAW16) 

And in the behavior definition of your BO use syntax “numbering: managed” for your key field  

That’s it, rest of the things will be managed by framework 

Creation of record for parent entity, in our case its hospital view, using early numbering managed 

As we can see the unique ID has been generated for us by the framework 

Now let’s see how to do it with child entity, in my case patient view 

Same steps we need to follow to achieve early numbering managed for child entity 

Behavior definition of patient view

Creation of record for child entity, in our case patient view using early numbering managed 

 

Early numbering unmanaged 

Unlike managed early numbering here in unmanaged early numbering we can have key fields of any data type 

Here in our scenario, I am not changing the data type of the field  

To start with early numbering unmanaged, go to your behavior definition and write the syntax early numbering 

Let’s start with parent entity, in our case hospital view 

Here if we see we are getting an error because at a time only one type of numbering can be used, so remove other numbering and keep the early numbering syntax 

Now if we see we are getting a warning at create method of Hospital entity 

The warning is related to implementing the method, so put cursor on the line and do a quick fix (CTRL + 1) 

System will give the quick fix suggestion to implement the method 

Double click and you will enter the behavior pool where you can write implementation for this method 

So, let’s write a basic logic to understand unmanaged early numbering 

Before writing the logic put cursor on the method name and click F2 to see the parameters related to the method 

Here we need to mandatorily fill mapped parameter consisting of %CID and our key field hospitalID 

%CID refers to content id which should be unique while creation of new record, this %CID we can refer from entities parameter 

So, let’s start writing the code for it 

 

METHOD earlynumbering_create.
SELECT MAX( hospital_id ) FROM zismo_dt_hosp INTO (lv_hos_id).

lv_hos_id = COND #( WHEN lv_hos_id IS NOT INITIAL THEN lv_hos_id + 1
ELSE 1 ).
mapped-hospital = VALUE #( ( %cid = entities[ 1 ]-%cid
HospitalId = lv_hos_id ) ).
ENDMETHOD.

 

It’s a simple logic where i am checking for maximum hospital id present in the DB and if present then i will increment by one else i will start id by 1 

And i am filling in the mapped parameter for hospital view.  

Creation of record for parent entity in our case hospital view using early numbering unmanaged 

As we can see the record has been created using the logic we implemented for unmanaged early numbering 

Now let’s see how to do it with child entity, in my case patient view 

Go to the behavior definition of patient view and write the syntax early numbering 

Since creation of child entity is dependent on parent entity so the warning is being triggered at behavior definition of parent entity at association 

So quick fix the warning and enter behavior pool 

cba means create by association 

So, let’s write a sample implementation to understand create by association in unmanaged early numbering 

Before writing the logic let’s check the method signature by clicking F2 

Here inside entities, we don’t have child entity’s key field patientid 

So, if we click on %target then we can see the components related to child entity 

So, we need to fill patientID present in %target and then we can append %target structure to mapped parameter of patient view 

 

METHOD earlynumbering_cba_Patient.
SELECT MAX( patient_id ) FROM zismo_dt_patient INTO (lv_pat_id).

lv_pat_id = COND #( WHEN lv_pat_id IS NOT INITIAL THEN lv_pat_id + 1
ELSE 1 ).

DATA(ls_target) = entities[ 1 ]-%target[ 1 ].
ls_target-PatientId = lv_pat_id.

APPEND CORRESPONDING #( ls_target ) TO mapped-patient.
ENDMETHOD.

 

Creation of child entity in our case patient view, using unmanaged cba early numbering 

 

Late numbering 

In late numbering also we can do numbering for key fields of any data type 

To implement late numbering write the syntax late numbering in the behavior definition of hospital view 

And the moment we write late numbering for root/parent entity we get an error  

The error is if parent entity is implemented as late numbering, then child entity must also have to contain late numbering 

So, lets write late numbering for child entity’s behavior definition as well 

Now the error is gone but we get a warning to implement the adjust number method 

In case of late numbering every time method name will be adjust numbers where we can write the logic for late numbering 

So quick fix the warning and enter behavior pool where we can see the method 

Click F2 and analyze the method signature 

Now here in this method itself we must write the late numbering logic for both parent and child entity 

So, i have written a sample logic  

Here whenever we perform create operation the mapped parameter related to that entity will not be initial so by using this condition, we can write a logic 

Here to perform create by association we need to get the parent entity key value which we can get from %tmp of child entity, so based on that parent key the associated child will be created

 

METHOD adjust_numbers.
IF mapped-hospital IS NOT INITIAL.

SELECT MAX( hospital_id ) FROM zismo_dt_hosp INTO (lv_hos_id).

lv_hos_id = COND #( WHEN lv_hos_id IS NOT INITIAL THEN lv_hos_id + 1
ELSE 1 ).

DATA(ls_mapped_hos) = VALUE #( mapped-hospital[ 1 ] OPTIONAL ).

ls_mapped_hos-HospitalId = lv_hos_id.
APPEND CORRESPONDING #( ls_mapped_hos ) TO mapped-hospital.

ELSEIF mapped-patient IS NOT INITIAL.

SELECT MAX( patient_id ) FROM zismo_dt_patient INTO (lv_pat_id).

lv_pat_id = COND #( WHEN lv_pat_id IS NOT INITIAL THEN lv_pat_id + 1
ELSE 1 ).

DATA(ls_mapped_pat) = VALUE #( mapped-patient[ 1 ] OPTIONAL ).
ls_mapped_pat-HospitalId = ls_mapped_pat-%tmp-HospitalId.
ls_mapped_pat-PatientId = lv_pat_id.

APPEND CORRESPONDING #( ls_mapped_pat ) TO mapped-patient.
ENDIF.
ENDMETHOD.

 

Creation of record for parent entity in our case hospital view using late numbering 

Creation of child entity in our case patient view, using late numbering 

Yeah, this is about numbering in RAP 

One thing to be careful of is while performing numbering with draft based BO we need to fill %is_draft field.

Thanks and Regards. 

 

​ Introduction In SAP ABAP RESTful Application Programming Model (RAP), the concepts of Create and Create by Association are fundamental for managing data persistence in business objects. Implementing numbering mechanisms during these operations is essential to ensure unique identifiers for newly created entities.This blog explores strategies and best practices for numbering during the Create operation and Create by Association, highlighting how RAP supports these processes in both managed and unmanaged scenarios.Basic Information About Numbering Numbering in RAP refers to the process of assigning unique values to the key fields of business entities during Create operations.Types of Numbering Early Numbering:Primary key values are assigned immediately when a creation operation is initiated. This mechanism is triggered during the interaction phase. Types: Managed Early Numbering: The RAP framework automatically assigns a UUID (Universal Unique Identifier) to the key field during the create request. Applicable for key fields of type RAW (16) in managed scenarios. Unmanaged Early Numbering: Developers implement custom logic to assign key values during the creation operation. Use Cases: Suitable for scenarios requiring immediate key assignment, such as generating unique identifiers for new records upon clicking “Create.”   Late Numbering:Primary key values are assigned just before the data is saved to the database. Triggered during the save sequence phase. Implementation: Developers implement the ADJUST_NUMBERS method to handle late numbering. This method is invoked during the save sequence to assign key values. Scenario Example In this example, we have designed a scenario with two views: Hospital View (Root entity) Patient View (Child entity, dependent on Hospital View) The Hospital View is the root entity, and the Patient View is related to it via a composition relationship. The patient data cannot exist independently of the hospital data. Below are the CDS view definitions and behavior implementations for the scenario:  Hospital View @AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: ‘Hospital interface view’
@Metadata.ignorePropagatedAnnotations: true
@ObjectModel.usageType:{
serviceQuality: #X,
sizeCategory: #S,
dataClass: #MIXED
}
define root view entity zismo_i_hospital
as select from zismo_dt_hosp
composition [1..*] of zismo_i_patient as _patient
{
@UI.facet: [{
label: ‘Hospital information’,
purpose: #STANDARD,
type: #IDENTIFICATION_REFERENCE,
position: 10
},
{ label : ‘Patient information’,
purpose: #STANDARD,
type: #LINEITEM_REFERENCE,
position: 20,
targetElement: ‘_patient’ } ]

@UI.lineItem: [{ position: 10, label: ‘Hospital Id’ }]
@UI.identification: [{ position: 10, label: ‘Hospital Id’ }]
key hospital_id as HospitalId,

@UI.lineItem: [{ position: 20, label: ‘Hospital name’ }]
@UI.identification: [{ position: 20, label: ‘Hospital name’ }]
hospital_name as HospitalName,

@UI.lineItem: [{ position: 30, label: ‘Hospital location’ }]
@UI.identification: [{ position: 30, label: ‘Hospital location’ }]
hospital_location as HospitalLocation,

@UI.lineItem: [{ position: 40, label: ‘No of doctors’ }]
@UI.identification: [{ position: 40, label: ‘No of doctors’ }]
no_of_doctors as NoOfDoctors,

@UI.lineItem: [{ position: 50, label: ‘No of rooms’ }]
@UI.identification: [{ position: 50, label: ‘No of rooms’ }]
no_of_rooms as NoOfRooms,
_patient
}  Patient View  @AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: ‘Patient interface view’
@Metadata.ignorePropagatedAnnotations: true
@ObjectModel.usageType:{
serviceQuality: #X,
sizeCategory: #S,
dataClass: #MIXED
}
define view entity zismo_i_patient
as select from zismo_dt_patient
association to parent zismo_i_hospital as _hospital on $projection.HospitalId = _hospital.HospitalId
{
@UI.facet: [{
purpose: #STANDARD,
type: #IDENTIFICATION_REFERENCE,
position: 10
}]

@UI.lineItem: [{ position: 10, label: ‘Hospital Id’ }]
@UI.identification: [{ position: 10, label: ‘Hospital Id’ }]
key hospital_id as HospitalId,

@UI.lineItem: [{ position: 20, label: ‘Patient Id’ }]
@UI.identification: [{ position: 20, label: ‘Patient Id’ }]
key patient_id as PatientId,

@UI.lineItem: [{ position: 30, label: ‘Patient name’ }]
@UI.identification: [{ position: 30, label: ‘Patient name’ }]
patient_name as PatientName,

@UI.lineItem: [{ position: 40, label: ‘Medical cause’ }]
@UI.identification: [{ position: 40, label: ‘Medical cause’ }]
medical_cause as MedicalCause,

@UI.lineItem: [{ position: 50, label: ‘Doctor assigned’ }]
@UI.identification: [{ position: 50, label: ‘Doctor assigned’ }]
doctor_assigned as DoctorAssigned,

@UI.lineItem: [{ position: 60, label: ‘Room no’ }]
@UI.identification: [{ position: 60, label: ‘Room no’ }]
room_no as RoomNo,

@UI.lineItem: [{ position: 70, label: ‘Payment status’ }]
@UI.identification: [{ position: 70, label: ‘Payment status’ }]
payment_status as PaymentStatus,
_hospital
}  To manage the functionality of the scenario, I have created a behavior definition for the root view (Hospital View).  This behavior definition defines the operations and interactions that can be performed on the hospital entity and its associated patient entities.  managed implementation in class zbp_ismo_i_hospital unique;
strict ( 2 );

define behavior for zismo_i_hospital alias hospital
persistent table zismo_dt_hosp
lock master
authorization master ( instance )
{
create;
update;
delete;

field ( readonly : update ) HospitalId;
association _patient { create; }

mapping for zismo_dt_hosp
{
HospitalId = hospital_id;
HospitalName = hospital_name;
HospitalLocation = hospital_location;
NoOfDoctors = no_of_doctors;
NoOfRooms = no_of_rooms;
}
}

define behavior for zismo_i_patient alias patient
persistent table zismo_dt_patient
lock dependent by _hospital
authorization dependent by _hospital
{
update;
delete;

field ( readonly ) HospitalId;
field ( readonly : update ) PatientId;
association _hospital;

mapping for zismo_dt_patient
{
HospitalId = hospital_id;
PatientId = patient_id;
PatientName = patient_name;
MedicalCause = medical_cause;
DoctorAssigned = doctor_assigned;
RoomNo = room_no;
PaymentStatus = payment_status;
}
}  Step by Step implementation Early numbering managedLet’s start with parent entity, in our case hospital view For managed early numbering, ensure that the key field is of type SYSUUIDx16 (RAW16) And in the behavior definition of your BO use syntax “numbering: managed” for your key field  That’s it, rest of the things will be managed by framework Creation of record for parent entity, in our case its hospital view, using early numbering managed As we can see the unique ID has been generated for us by the framework Now let’s see how to do it with child entity, in my case patient view Same steps we need to follow to achieve early numbering managed for child entity Behavior definition of patient viewCreation of record for child entity, in our case patient view using early numbering managed  Early numbering unmanaged Unlike managed early numbering here in unmanaged early numbering we can have key fields of any data type Here in our scenario, I am not changing the data type of the field  To start with early numbering unmanaged, go to your behavior definition and write the syntax early numbering Let’s start with parent entity, in our case hospital view Here if we see we are getting an error because at a time only one type of numbering can be used, so remove other numbering and keep the early numbering syntax Now if we see we are getting a warning at create method of Hospital entity The warning is related to implementing the method, so put cursor on the line and do a quick fix (CTRL + 1) System will give the quick fix suggestion to implement the method Double click and you will enter the behavior pool where you can write implementation for this method So, let’s write a basic logic to understand unmanaged early numbering Before writing the logic put cursor on the method name and click F2 to see the parameters related to the method Here we need to mandatorily fill mapped parameter consisting of %CID and our key field hospitalID %CID refers to content id which should be unique while creation of new record, this %CID we can refer from entities parameter So, let’s start writing the code for it  METHOD earlynumbering_create.
SELECT MAX( hospital_id ) FROM zismo_dt_hosp INTO (lv_hos_id).

lv_hos_id = COND #( WHEN lv_hos_id IS NOT INITIAL THEN lv_hos_id + 1
ELSE 1 ).
mapped-hospital = VALUE #( ( %cid = entities[ 1 ]-%cid
HospitalId = lv_hos_id ) ).
ENDMETHOD.  It’s a simple logic where i am checking for maximum hospital id present in the DB and if present then i will increment by one else i will start id by 1 And i am filling in the mapped parameter for hospital view.  Creation of record for parent entity in our case hospital view using early numbering unmanaged As we can see the record has been created using the logic we implemented for unmanaged early numbering Now let’s see how to do it with child entity, in my case patient view Go to the behavior definition of patient view and write the syntax early numbering Since creation of child entity is dependent on parent entity so the warning is being triggered at behavior definition of parent entity at association So quick fix the warning and enter behavior pool cba means create by association So, let’s write a sample implementation to understand create by association in unmanaged early numbering Before writing the logic let’s check the method signature by clicking F2 Here inside entities, we don’t have child entity’s key field patientid So, if we click on %target then we can see the components related to child entity So, we need to fill patientID present in %target and then we can append %target structure to mapped parameter of patient view  METHOD earlynumbering_cba_Patient.
SELECT MAX( patient_id ) FROM zismo_dt_patient INTO (lv_pat_id).

lv_pat_id = COND #( WHEN lv_pat_id IS NOT INITIAL THEN lv_pat_id + 1
ELSE 1 ).

DATA(ls_target) = entities[ 1 ]-%target[ 1 ].
ls_target-PatientId = lv_pat_id.

APPEND CORRESPONDING #( ls_target ) TO mapped-patient.
ENDMETHOD.  Creation of child entity in our case patient view, using unmanaged cba early numbering  Late numbering In late numbering also we can do numbering for key fields of any data type To implement late numbering write the syntax late numbering in the behavior definition of hospital view And the moment we write late numbering for root/parent entity we get an error  The error is if parent entity is implemented as late numbering, then child entity must also have to contain late numbering So, lets write late numbering for child entity’s behavior definition as well Now the error is gone but we get a warning to implement the adjust number method In case of late numbering every time method name will be adjust numbers where we can write the logic for late numbering So quick fix the warning and enter behavior pool where we can see the method Click F2 and analyze the method signature Now here in this method itself we must write the late numbering logic for both parent and child entity So, i have written a sample logic  Here whenever we perform create operation the mapped parameter related to that entity will not be initial so by using this condition, we can write a logic Here to perform create by association we need to get the parent entity key value which we can get from %tmp of child entity, so based on that parent key the associated child will be created METHOD adjust_numbers.
IF mapped-hospital IS NOT INITIAL.

SELECT MAX( hospital_id ) FROM zismo_dt_hosp INTO (lv_hos_id).

lv_hos_id = COND #( WHEN lv_hos_id IS NOT INITIAL THEN lv_hos_id + 1
ELSE 1 ).

DATA(ls_mapped_hos) = VALUE #( mapped-hospital[ 1 ] OPTIONAL ).

ls_mapped_hos-HospitalId = lv_hos_id.
APPEND CORRESPONDING #( ls_mapped_hos ) TO mapped-hospital.

ELSEIF mapped-patient IS NOT INITIAL.

SELECT MAX( patient_id ) FROM zismo_dt_patient INTO (lv_pat_id).

lv_pat_id = COND #( WHEN lv_pat_id IS NOT INITIAL THEN lv_pat_id + 1
ELSE 1 ).

DATA(ls_mapped_pat) = VALUE #( mapped-patient[ 1 ] OPTIONAL ).
ls_mapped_pat-HospitalId = ls_mapped_pat-%tmp-HospitalId.
ls_mapped_pat-PatientId = lv_pat_id.

APPEND CORRESPONDING #( ls_mapped_pat ) TO mapped-patient.
ENDIF.
ENDMETHOD.  Creation of record for parent entity in our case hospital view using late numbering Creation of child entity in our case patient view, using late numbering Yeah, this is about numbering in RAP One thing to be careful of is while performing numbering with draft based BO we need to fill %is_draft field.Thanks and Regards.    Read More Application Development Blog Posts articles 

#SAP

You May Also Like

More From Author