
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.
Numbering in RAP refers to the process of assigning unique values to the key fields of business entities during Create operations.
Types of Numbering
Implementation:
In this example, we have designed a scenario with two views:
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;
}
}
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
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
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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
9 | |
5 | |
4 | |
4 | |
2 | |
2 | |
2 | |
2 | |
2 |