** RAP初学两三问 **
**前言**
由于最近开展的内部培训,使得我开始接触RAP。作为一名ABAP开发者我逐渐了解到,随着ABAP的不断进化,如今我们有了新的编程模型:Restful ABAP
Programming模型,简称为RAP模型。该模型定义了一套架构体系,我们能够凭借其来高效地进行应用的端到端开发。
接下来我将与大家分享RAP相关的六个基本问题。
**Q1**
**ABAP与RAP有什么区别?**
**Q2**
**什么是CDS?**
**Q3**
**CDS View有哪些种类?**
**Q4**
**CDS中数据有哪些连接,有什么
**
**需要注意的?**
**Q5**
**RAP的开发架构主要分为几层?**
**Q6**
**RAP ListReport如何实现?**
以下内容整理自 SAP 官方 ABAP 速查表(主题:ABAP EML for RAP),作为本文的扩展补充资料。
ABAP Entity Manipulation Language (or EML for short) is a subset of ABAP that allows you to access the data of RAP business objects in an ABAP program. The following points cover RAP-related terms such as RAP business objects and others for setting the context:
| Terms | Notes |
|
RAP business objects (RAP BO) |
of CDS entities of a data model
entities](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenparent_entity_glosry.htm "Glossary Entry") and child entities that are themselves defined using CDS compositions and to-parent associations.
tree](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_composition_tree_glosry.htm "Glossary Entry") is the root entity that represents the business object. With a large composition tree, RAP BOs can be fairly complex. Or they can be very simple by just consisting of one root entity alone.
|
|
RAP behavior definition (BDEF) |
DDIC artifact: RAP behavior definition (BDEF)
behavior](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_bo_behavior_glosry.htm "Glossary Entry") (i. e. the transactional behavior of a RAP BO)
characteristics](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_entity_properties_glosry.htm "Glossary Entry") and RAP BO operations i. e. RAP BO standard operations (CRUD operations), non-standard operations like specific RAP actions and functions, and more.
RAP BO behavior like RAP feature control, for example, defining which data is mandatory and which is read-only, or determinations and validations.
Language](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbdl_glosry.htm "Glossary Entry") (BDL) for the definitions. Find more information on the topic and various options to define the transactional behavior in section BDL for Behavior Definitions in the ABAP Keyword Documentation. |
|
Transactional buffer and implementation types |
its data. This data is available in the RAP transactional buffer.
during an SAP LUW.
instances](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_bo_instance_glosry.htm "Glossary Entry") (i. e. concrete data sets of an entity). This is where EML enters the picture: EML is used, among others, to access this data in the transactional buffer.
managed and unmanaged RAP BOs.
specified in the BDEF.
provider](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_bo_provider_glosry.htm "Glossary Entry"), i. e. how the transactional buffer is provided and how the behavior of a RAP BO is implemented. |
|
Managed RAP BOs |
transactional buffer and RAP BO behavior (for standard operations only). In this case, the developers need not cater for the transactional buffer and implement the standard operations. This implementation is mostly relevant for greenfield scenarios when starting from scratch.
developers need not cater for an implementation at all. The standard operations work out of the box. For example, in case of an update operation, RAP BO instance data that is to be updated is automatically read into the transactional buffer, and then updated accordingly there. Finally, when triggering the saving, the updated instance in the transactional buffer is automatically saved to the database without any custom development needed.
create the buffer yourself.
additional implementations also in the context of managed RAP BOs. For example, non-standard operations or feature controls must be self-implemented in ABAP behavior pools (see the details further down). |
|
Unmanaged RAP BOs |
provider](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenunmanaged_rap_bo_prov_glosry.htm "Glossary Entry"), i. e. the transactional buffer and all RAP BO operations must be provided or self-implemented by developers in an ABAP behavior implementation
scenarios, i. e. in scenarios in which transactional buffers and application logic is already available and should be embedded in the RAP world. Note that it is possible to have a managed RAP BO with unmanaged parts, e.g. unmanaged save or additional save. Find more information here. |
|
ABAP behavior implementation in an ABAP behavior pool (ABP) |
pool](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbehavior_pool_glosry.htm "Glossary Entry") is a special class pool for an ABAP behavior implementation that implements the unmanaged RAP BO provider based on definitions in a BDEF. The class pool's name is specified in the BDEF.
class](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenglobal_class_glosry.htm "Glossary Entry") of a behavior pool does not implement the behavior itself. It is empty on creation apart from the declaration and implementation part skeletons. The behavior implementation is coded in local RAP handler classes and a RAP saver class in the CCIMP include of the behavior pool. These classes are called by the RAP runtime engine when the RAP BO is accessed. This is covered in more detail further down.
for special variants of managed RAP BOs such as RAP additional save and RAP unmanaged save). Local handler classes are usually needed in managed RAP BOs if implementations are required that go beyond standard operations.
consist of many entities, you can define behavior pools for individual entities by adding the syntax to the |
[!NOTE] - Find more terms in the RAP Glossary of the ABAP Keyword Documentation. - There are more artifacts and concepts related to RAP that go way beyond the scope of this cheat sheet. For example, a RAP BO can be exposed as a business service to be accessed from outside AS ABAP and consumed. A [RAP BO
consumer](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_bo_consumer_glosry.htm "Glossary Entry") is either the RAP transactional engine that handles requests from outside the AS ABAP or, from inside AS ABAP, an ABAP program using ABAP EML (which this cheat sheet and the examples focus on).
- The cheat sheet and the examples focus on a minimal number of artifacts - from database table and view entity, to BDEF and ABAP behavior pool, including an ABAP class as consumer. Many other RAP-related artifacts and aspects are beyond the scope. Get a more thorough insight in the Development guide for the ABAP RESTful Application Programming Model. - You can create all RAP service-related repository objects from scratch using a wizard in ADT. The wizard lets you manually input your RAP BO requirements or use the Joule chat. Find more information here.
You can access RAP BO data from inside AS ABAP using EML. Among other things, EML allows you to read or modify RAP BOs by accessing the RAP BO data (the RAP BO instances) in the transactional buffer and trigger the persistent storage or reset changes. More precisely, when EML statements are executed, the calling of RAP handler methods is triggered to access the transactional buffer of a RAP BO. As mentioned, for unmanaged RAP BOs or unmanaged parts of managed RAP BOs, the handler methods that are called are part of an ABAP behavior pool.
The global class of an ABP has the addition FOR BEHAVIOR OF bdef to the definition while bdef stands for the name of the BDEF. This class is (initially) empty apart from the declaration and implementation part skeleton.
CLASS zbp_demo_abap_rap_draft_m DEFINITION PUBLIC ABSTRACT FINAL FOR BEHAVIOR OF zdemo_abap_rap_draft_m.
ENDCLASS.
CLASS zbp_demo_abap_rap_draft_m IMPLEMENTATION.
ENDCLASS.The actual implementation is done in local classes in the CCIMP include (Local Types tab in ADT) of the behavior pool. There, two kinds of local classes are to be defined and implemented that are related to the RAP BO's runtime: one or more handler classes to implement the RAP BO behavior (in RAP handler methods) during the RAP interaction phase (the data reading and modification phase) and a saver class to implement the RAP save sequence (in saver methods to save data from the transactional buffer to the database).
modularization purposes, one behavior pool can define multiple handler classes. For example, each entity can have its own handler class, or individual handler classes can be defined to distinguish between reading and changing RAP BO entities.
CL_ABAP_BEHAVIOR_HANDLER.
ABSTRACT and FINALsince instantiating and calling only happens through the RAP runtime engine.
helps you create the classes and methods (and basically the ABP as such) when creating the BDEF. A quick fix is available that creates the method definitions and a skeleton of the implementations automatically.
Example: Handler class definition
CLASS lhc_root DEFINITION INHERITING FROM cl_abap_behavior_handler.
...
ENDCLASS....` followed by the kinds of operations. There are various options depending on the RAP BO operation.
with dedicated method parameters. For example, an action might be defined with a result parameter, hence, the method must be defined with the addition RESULT and a parameter.
FOR MODIFY handler method can handle multiple entitiesand operations, i. e. not only create but also update or delete might be integrated in the method definition. However, it might be useful to split the handler method into separate methods for better readability.
Example: Handler method definitions
"Create
METHODS create FOR MODIFY
IMPORTING entities FOR CREATE bdef.
"Read: Specifying a read result is mandatory.
METHODS read FOR READ
IMPORTING keys FOR READ bdef RESULT result.
"Action: action name is preceded by the BDEF name and a tilde after FOR ACTION
METHODS some_action FOR MODIFY
IMPORTING keys FOR ACTION bdef~some_action.FOR MODIFY, FOR CREATE or FOR READ as well as mandatory or optional additions like RESULT that are followed by parameters.
types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_derived_type_glosry.htm "Glossary Entry") that have special RAP-related components as covered further down.
the method names except for some predefined names.
Specifying the addition IMPORTING explicitly is optional since it is used implicitly. In most cases, entire instances or just key values of instances are imported.
explicitly specified in the definition but implicitly used. The explicit specification of the CHANGING addition is not needed. In most cases, these are RAP response parameters. The following image shows the F2 information in ADT for the create handler method. 
mapped, failed andreported (the names are predefined) can be considered as containers for information - information a RAP BO consumer is provided with by a RAP BO provider, for example, an SAP Fiori app displays an error message if something went wrong. The availability of the parameters depends on the handler method used (e. g. mapped is only available for operations creating instances).
mapped: Used to provide mapping information on RAP BOinstances, for example, which key values were created for given content IDs ( %cid).
failed: Information for identifying the data set forwhich an error occurred in a RAP operation
reported: Used, for example, to exchange error messages for eachentity defined in the BDEF and not related to a specific entity.
reported parameter is adeep structure containing, for example, the messages of the root entity and child entities. For example, if a create operation fails for a RAP BO instance of the root entity, a message, information about the instance key and other things can be included in this parameter which is passed to a RAP BO consumer. You could imagine that such an error message is displayed on an SAP Fiori UI if something goes wrong to inform the user.
[!NOTE] It is essential to implement RAP handler methods correctly to ensure the stability and consistency of RAP business objects, particularly in populating the RAP response parameters. For more details on best practices for implementation, refer to the documentation.
sequence](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_save_seq_glosry.htm "Glossary Entry"). A saver class is usually only available in unmanaged RAP BOs (except for special variants of managed RAP BOs that are not outlined here).
ABSTRACT and FINALsince the instantiating and calling only happens through the RAP runtime engine.
behavior pool. It includes the definitions and implementations of RAP saver methods.
predefined names. Some of them are mandatory to implement, some are optional. The adjust_numbers method is only available in late numbering scenarios.
CL_ABAP_BEHAVIOR_SAVER. The saver methods are declared by redefining predefined methods of the superclass. They implicitly have response parameters.
of RAP BO instances as import parameter. Therefore, instance data must be handled via the transactional buffer when self-implementing the saver methods.
ENTITIES](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcommit_entities.htm) statement. Note that in natively supported RAP scenarios, for example, an SAP Fiori app using OData, the COMMIT ENTITIES` call is performed implicitly and automatically by the RAP runtime engine.
here.
Example: Definition of a RAP saver class and saver methods
CLASS lsc_bdef DEFINITION INHERITING FROM cl_abap_behavior_saver.
PROTECTED SECTION.
"For final calculations and data modifications involving all
"BOs in the current RAP transaction
METHODS finalize REDEFINITION.
"Checks the consistency of the transactional buffer before
"the save method saves data to the database
METHODS check_before_save REDEFINITION.
"Preliminary IDs are mapped to final keys. Only for late numbering.
METHODS adjust_numbers REDEFINITION.
"Saves the current state of the transactional buffer to the database
METHODS save REDEFINITION.
"Clear the transactional buffer
METHODS cleanup REDEFINITION.
METHODS cleanup_finalize REDEFINITION.
ENDCLASS.... FOR BEHAVIOR OF bdef_name .... IN LOCAL MODE and PRIVILEGED can be used. auxiliary class ... notation. Multiple ABAP auxiliary classes can be specified. The operands of EML statements and parameters of handler and saver methods are mainly special messenger tables for passing data and receiving results or messages, i. e. the communication between a RAP BO consumer and the RAP BO provider using EML consists (in most cases) of exchanging data stored in internal tables that have special ABAP types - BDEF derived types. These types are tailor-made for RAP purposes.
As the name implies, the types are derived by the ABAP runtime framework from CDS entities and their behavior definition in the BDEF. With these special types, a type-safe access to RAP BOs is guaranteed.
[!NOTE] - To explore BDEF derived types in your RAP BO, you can access the CCIMP include (Local Types tab in ADT) of your ABAP behavior pool, position the cursor on the methods, choose F2 and check the parameters typed with BDEF derived types. - As mentioned, CRUD operations are implicitly supported in managed scenarios (when specified in the BDEF). So, there will not be method declarations and implementations for CRUD operation methods.
create specification in the BDEF), you can create respective BDEF derived types. If you do not enable delete operations, you cannot create respective types.FOR followed by further RAP-related additions (such as CREATE for create operations).| Syntax | Notes |
|---|---|
TYPE TABLE FOR | For creating internal tables with BDEF derived types. Most RAP handler method parameters use tabular BDEF derived types. |
TYPE STRUCTURE FOR | In many cases, structures of type TYPE STRUCTURE FOR serve as both the work area and the line type of the internal tables. There are also structured BDEF derived types that function as types for RAP handler method parameters. |
TYPE RESPONSE FOR | These types refer to the RAP response parameters mapped, failed, and reported. They are deep structures containing information for individual RAP BO entities. The components of these structures are internal tables of appropriate types with TYPE TABLE FOR. |
TYPE REQUEST FOR | The types TYPE REQUEST FOR CHANGE and TYPE REQUEST FOR DELETE are relevant for importing parameters of the save_modified RAP saver method in the context of RAP additional and unmanaged save. These BDEF derived types are deep structures containing internal tables with RAP BO instance keys and/or data for create, update, or delete operations. |
TYPES and DATA statements to declare data types and objects with BDEF derived types.DATA d1 TYPE TABLE FOR CREATE zdemo_abap_rap_ro_m.d1 and press F2 to get type information. The long form shows the root entity plus the concrete entity (which is the root entity itself, an alias name is specified for the root entity in the example): d1 type table for create zdemo_abap_rap_ro_m\\root.\\ and an entity of the composition tree.DATA d2 TYPE TABLE FOR CREATE zdemo_abap_rap_ro_m\\zdemo_abap_rap_ro_m.DATA d1 TYPE TABLE FOR CREATE zdemo_abap_rap_ro_m. (root entity), DATA d3 TYPE TABLE FOR UPDATE zdemo_abap_rap_ch_m. (child entity). Note that most example codes in the cheat sheet and in the executable example use the short form.\: For example, DATA d4 TYPE TABLE FOR CREATE zdemo_abap_rap_ro_m\_child.. The long form with \\ followed by an entity name, \, and an association is also possible.[!NOTE] Certain types derived from the BDEF can only be specified and used within implementation classes, not beyond. These types include the following:FOR CHANGE,FOR DETERMINATION,FOR VALIDATION,FOR ... FEATURES,FOR ... AUTHORIZATION.
BDEF derived type examples:
[!NOTE] The demo BDEFzdemo_abap_rap_ro_m... - specifies the alias namerootfor the RAP BO root entityzdemo_abap_rap_ro_m. - specifies the association_child. - includes the child entityzdemo_abap_rap_ch_m, for which an alias namechildis specified and which specifies the association_parent.
*&---------------------------------------------------------------------*
*& BDEF derived types demonstrating long and short forms
*&---------------------------------------------------------------------*
"Short forms
"Specifying the RAP BO root entity
TYPES t1 TYPE TABLE FOR CREATE zdemo_abap_rap_ro_m.
DATA d1 TYPE TABLE FOR CREATE zdemo_abap_rap_ro_m.
"Specifying child entity
TYPES t2 TYPE TABLE FOR UPDATE zdemo_abap_rap_ch_m.
DATA d2 TYPE TABLE FOR UPDATE zdemo_abap_rap_ch_m.
"Long form: Specifying the name of the RAP BO root entity, followed
"by \\ and an entity of the composition tree
"Since an alias name is specified for the example entities, it must
"be specified after \\. Otherwise, the entity name can be specified.
"t3/d3 are the same as t1/d1.
TYPES t3 TYPE TABLE FOR CREATE zdemo_abap_rap_ro_m\\root.
DATA d3 TYPE TABLE FOR CREATE zdemo_abap_rap_ro_m\\root.
"In this example, t4/d4 are the same as t2/d2.
TYPES t4 TYPE TABLE FOR UPDATE zdemo_abap_rap_ro_m\\child.
DATA d4 TYPE TABLE FOR UPDATE zdemo_abap_rap_ro_m\\child.
"Specifying associations that are declared in the BDEF preceded by \
"with both short and long forms
"In this example, t5/d5 are the same as t6/d6.
TYPES t5 TYPE TABLE FOR CREATE zdemo_abap_rap_ro_m\_child.
DATA d5 TYPE TABLE FOR CREATE zdemo_abap_rap_ro_m\_child.
TYPES t6 TYPE TABLE FOR CREATE zdemo_abap_rap_ro_m\\root\_child.
DATA d6 TYPE TABLE FOR CREATE zdemo_abap_rap_ro_m\\root\_child.
"In this example, t7/d7 are the same as t8/d8.
TYPES t7 TYPE TABLE FOR READ IMPORT zdemo_abap_rap_ro_m\\child\_parent.
DATA d7 TYPE TABLE FOR READ IMPORT zdemo_abap_rap_ro_m\\child\_parent.
TYPES t8 TYPE TABLE FOR READ IMPORT zdemo_abap_rap_ch_m\_parent.
DATA d8 TYPE TABLE FOR READ IMPORT zdemo_abap_rap_ch_m\_parent.
*&---------------------------------------------------------------------*
*& Miscellaneous BDEF derived types
*&---------------------------------------------------------------------*
"The examples show a selection of possible types. The types mostly use
"the short form.
*&---------------------------------------------------------------------*
*& Table types
*&---------------------------------------------------------------------*
"Create
DATA create_tab TYPE TABLE FOR CREATE zdemo_abap_rap_ro_m.
"Update
DATA update_tab TYPE TABLE FOR UPDATE zdemo_abap_rap_ro_m.
"Create-by-association operation specifying the name of the entity
"and the association
DATA cba_tab TYPE TABLE FOR CREATE zdemo_abap_rap_ro_m\_child.
"Action; the name of the action is preceded by a tilde
DATA action_import TYPE TABLE FOR ACTION IMPORT zdemo_abap_rap_ro_m~multiply_by_2.
"The example action does not specify a result parameter, therefore the following
"type is not available.
"DATA action_result TYPE TABLE FOR ACTION RESULT zdemo_abap_rap_ro_m~multiply_by_2.
"Read
DATA read_import TYPE TABLE FOR READ IMPORT zdemo_abap_rap_ro_m.
DATA read_result TYPE TABLE FOR READ RESULT zdemo_abap_rap_ro_m.
"The previous examples use the RAP BO root entity. The following ones
"use a child entity specified in the example BDEF.
"Update
DATA update_tab_ch TYPE TABLE FOR UPDATE zdemo_abap_rap_ch_m.
"Which corresponds to the long form sepcifying the RAP BO root entity
"name and the (alias) name of the child entity followed by \\
DATA update_tab_ch_2 TYPE TABLE FOR UPDATE zdemo_abap_rap_ro_m\\child.
DATA delete_tab_ch TYPE TABLE FOR DELETE zdemo_abap_rap_ch_m.
"Read-by-association
DATA rba_import_child_to_parent TYPE TABLE FOR READ IMPORT zdemo_abap_rap_ch_m\_parent.
DATA rba_import_child_to_parent_2 TYPE TABLE FOR READ IMPORT zdemo_abap_rap_ro_m\\child\_parent.
DATA rba_result_child_to_parent TYPE TABLE FOR READ RESULT zdemo_abap_rap_ch_m\_parent.
DATA rba_result_child_to_parent_2 TYPE TABLE FOR READ IMPORT zdemo_abap_rap_ro_m\\child\_parent.
*&---------------------------------------------------------------------*
*& Structured types
*&---------------------------------------------------------------------*
DATA create_wa TYPE STRUCTURE FOR CREATE zdemo_abap_rap_ro_m.
DATA update_wa TYPE STRUCTURE FOR UPDATE zdemo_abap_rap_ro_m.
TYPES delete_wa TYPE STRUCTURE FOR DELETE zdemo_abap_rap_ro_m.
DATA update_child_wa TYPE STRUCTURE FOR UPDATE zdemo_abap_rap_ch_m.
TYPES delete_child_wa TYPE STRUCTURE FOR DELETE zdemo_abap_rap_ch_m.
"Retrieving permissions
DATA perm_req TYPE STRUCTURE FOR PERMISSIONS REQUEST zdemo_abap_rap_ro_m.
"Retrieving global features
"... FOR ... FEATURES ... can only be used within implementation classes
"DATA feat_req TYPE STRUCTURE FOR GLOBAL FEATURES RESULT zdemo_abap_rap_ro_m.
"The same applies to validations and determinations
"DATA validate TYPE TABLE FOR VALIDATION zdemo_abap_rap_ro_m~val.
"DATA determine TYPE TABLE FOR DETERMINATION zdemo_abap_rap_ro_m~det_add_text.
*&---------------------------------------------------------------------*
*& BDEF derived types relating to RAP response parameters
*&---------------------------------------------------------------------*
"Response parameters
"Note: The addition EARLY or no addition is relevant in the context of the
"RAP interaction phase. The addition LATE is relevant in the context of the
"save phase.
DATA map TYPE RESPONSE FOR MAPPED zdemo_abap_rap_ro_m.
DATA fail TYPE RESPONSE FOR FAILED zdemo_abap_rap_ro_m.
DATA resp TYPE RESPONSE FOR REPORTED zdemo_abap_rap_ro_m.
"Same as resp
DATA resp_2 TYPE RESPONSE FOR REPORTED EARLY zdemo_abap_rap_ro_m.
"Relevant for the late RAP save phase
DATA map_late TYPE RESPONSE FOR MAPPED LATE zdemo_abap_rap_ro_m.
DATA fail_late TYPE RESPONSE FOR FAILED LATE zdemo_abap_rap_ro_m.
DATA resp_late TYPE RESPONSE FOR REPORTED LATE zdemo_abap_rap_ro_m.
"You can check the F2 information in ADT for the types. The types above
"are deep structures, containing tables typed with TYPE TABLE FOR MAPPED
"and so on.
DATA map_tab_early_1 TYPE TABLE FOR MAPPED zdemo_abap_rap_ro_m.
DATA map_tab_early_2 TYPE TABLE FOR MAPPED EARLY zdemo_abap_rap_ro_m.
DATA map_tab_late TYPE TABLE FOR MAPPED LATE zdemo_abap_rap_ro_m.
*&---------------------------------------------------------------------*
*& BDEF derived types relating to the save phase in RAP additional
*& and unmanaged save scenarios
*&---------------------------------------------------------------------*
"REQUEST FOR ... can only be used within implementation classes
"For create and update operations
"DATA req_change TYPE REQUEST FOR CHANGE zdemo_abap_rap_ro_m_as.
"For delete operations
"DATA req_delete TYPE REQUEST FOR DELETE zdemo_abap_rap_ro_m_as.
*&---------------------------------------------------------------------*
*& Excursion: Typing method parameters with BDEF derived types
*&---------------------------------------------------------------------*
"TYPES tab_type TYPE TABLE FOR CREATE zdemo_abap_rap_ro_m.
"METHODS some_meth IMPORTING itab TYPE tab_type.Many of the BDEF derived types contain components of CDS entities like key and data fields that retain their original data type, for example, a messenger table typed with TYPE TABLE FOR CREATE. Certainly, if an instance is to be created, key and field values of a RAP BO instance are of relevance.
Yet, all BDEF derived types contain special RAP components serving a dedicated purpose. The names of these RAP components begin with % to avoid naming conflicts with components of the CDS entities. The following image shows the F2 information of a BDEF derived type containing the % components and fields from the CDS entity.

Some of the % components are component groups summarizing groups of table columns under a single name. In doing so, they simplify the handling of derived types for developers. For example, the component group %data contains all primary key and data fields of a RAP BO entity (actually, by containing the keys, it also contains the component group %key in the case above). The F2 information in ADT helps you find out about the available components in a variable. The image below shows the details of %data when clicking the derived type link in the first ADT F2 information screen.

The availability of % components depends on definitions in the BDEF. Their availability also depends on more criteria, for example, the scenario. For example, the component %pid that represents a preliminary ID for a RAP BO instance is only available in late numbering scenarios. The draft indicator %is_draft is only relevant in the context of draft.
The following table covers a selection of available BDEF derived type components. Find more details on the available components in section Components of BDEF Derived Types of the ABAP Keyword Documentation.
| Component | Notes | Code Snippet |
|---|---|---|
RAP BO operations in which instances are created and especially in cases where the key values of RAP BO instances are not yet determined
request and the key value has not yet been determined. In the same request - a save has not yet been triggered - an update is requested for this RAP BO instance. Using the content ID, it is guaranteed that the update operation happens for the desired instance. For this purpose, derived types for operations like update or delete include the component
needed. The specified content ID is only valid within one ABAP EML request. You can use the optional addition |
| |
BO instance.
instead of |
The code snippet visualizes various specification options regarding | |
and data fields of a RAP BO instance, which indicate flags.
flag for which fields are requested by RAP BO providers or RAP BO consumers respectively during the current EML request.
particular non-key fields in |
| |
|
| |
|
|
The following code snippet illustrates the importance of careful component access and value assignment with component groups in BDEF derived types:
FOR CREATE as an example.%data and %key.%data contains %key as a component.DATA cr_tab TYPE TABLE FOR CREATE zdemo_abap_rap_ro_m.
cr_tab = VALUE #( ( key_field = 1 ) ).
DATA(a) = cr_tab[ 1 ]-key_field.
DATA(b) = cr_tab[ 1 ]-%key-key_field.
DATA(c) = cr_tab[ 1 ]-%data-key_field.
DATA(d) = cr_tab[ 1 ]-%data-%key-key_field.
"Even more specification options with another BDEF derived type.
"This is only to visualize the variety of component groups in BDEF
"derived types.
DATA upd_tab TYPE TABLE FOR UPDATE zdemo_abap_rap_ro_m.
upd_tab = VALUE #( ( key_field = 1 ) ).
DATA(e) = upd_tab[ 1 ]-key_field.
DATA(f) = upd_tab[ 1 ]-%key-key_field.
DATA(g) = upd_tab[ 1 ]-%tky-%key-key_field.
DATA(h) = upd_tab[ 1 ]-%tky-key_field.
DATA(i) = upd_tab[ 1 ]-%tky-%pky-%key-key_field.
DATA(j) = upd_tab[ 1 ]-%tky-%pky-key_field.
DATA(k) = upd_tab[ 1 ]-%pky-key_field.
DATA(l) = upd_tab[ 1 ]-%pky-%key-key_field.
DATA(m) = upd_tab[ 1 ]-%data-%key-key_field.
DATA(o) = upd_tab[ 1 ]-%data-key_field.Several BDEF derived types contain % components, which have a specific type and represent flags. The mentioned %control structure, whose components are of type ABP_BEHV_FLAG, is such a component. When assigning values to these components, ensure you use appropriate values. The IF_ABAP_BEHV interface provides a range of structured constants for this purpose. Although these constants are technically identical, it is recommended that you use them in the right context.
| Type | Structured Constant | Details |
|---|---|---|
ABP_BEHV_FLAG | IF_ABAP_BEHV=>MK | Marks and unmarks fields in ABAP EML modify and read operations, such as in %control and %element. |
ABP_BEHV_FIELD_PERM | IF_ABAP_BEHV=>PERM-F | Used in the context of field permission results, such as a field marked as mandatory or read-only. |
ABP_BEHV_OP_PERM | IF_ABAP_BEHV=>PERM-O | For operation permission results, such as a delete operation that is marked as enabled. |
ABP_BEHV_FIELD_CTRL | IF_ABAP_BEHV=>FC-F | For field feature control results, such as a field marked with no restrictions. |
ABP_BEHV_OP_CTRL | IF_ABAP_BEHV=>FC-O | For operation feature control results, such as a disabled update operation. |
ABP_BEHV_AUTH | IF_ABAP_BEHV=>AUTH | For authorization results, such as an unauthorized operation. |
IF_ABAP_BEHV=>T_CHAR01 | IF_ABAP_BEHV=>OP | For dynamic ABAP EML statements; e.g. if_abap_behv=>op-m-create for create and if_abap_behv=>op-r-read for read operations. |
IF_ABAP_BEHV=>T_CHAR01 | IF_ABAP_BEHV=>COP | For accumulated change operation information such as in the context of draft additional save; e.g. if_abap_behv=>cop-update for update operations. |
TYPE TABLE FOR ...) are standard tables with an empty primary table key (primary_key). entity: Includes %keycid: Includes %cid or %cid_ref, and can - depending on the type - also include %key and %piddraft: Available in draft scenarios; includes %is_draft; can also include %key and %pidpid: Available in late numbering scenarios; includes %pid; can also include %tmp and %keyid is available for either entity, draft, or pid depending on the context. Check the F2 information in ADT for the respective types.DATA itab_cr TYPE TABLE FOR CREATE zdemo_abap_rap_ro_m.
itab_cr = VALUE #( %control-key_field = if_abap_behv=>mk-on
%control-field1 = if_abap_behv=>mk-on
%control-field2 = if_abap_behv=>mk-on
%control-field3 = if_abap_behv=>mk-on
%control-field4 = if_abap_behv=>mk-on
( %cid = `cid1`
%key-key_field = 1
field1 = 'aaa'
field2 = 'bbb'
field3 = 11
field4 = 111 ) ).
"Secondary table keys available in the example table: cid, entity
"The statements demonstrate the secondary table keys using table expressions.
"The statements commented out raise a syntax warning. The secondary table key
"should be specified explicitly.
"DATA(line_a) = itab_cr[ %cid = `cid1` ].
"DATA(line_b) = itab_cr[ %cid = `cid1` %key = VALUE #( key_field = 1 ) ].
DATA(line_c) = itab_cr[ KEY cid COMPONENTS %cid = `cid1`
%key = VALUE #( key_field = 1 ) ].
"DATA(line_d) = itab_cr[ %key = VALUE #( key_field = 1 ) ].
"The COMPONENTS addition is optional.
DATA(line_e) = itab_cr[ KEY entity %key = VALUE #( key_field = 1 ) ].The CORRESPONDING operator offers RAP-specific additions for handling type mappings related to BDEF derived types and other types. For more information, see the ABAP Keyword Documentation topic.
The following additions are available:
... CORRESPONDING ...( ... MAPPING FROM ENTITY ) ...
... CORRESPONDING ...( ... MAPPING TO ENTITY ) ...
... CORRESPONDING ...( ... USING CONTROL ) ...
... CORRESPONDING ...( ... MAPPING FROM ENTITY USING CONTROL ) ...
... CORRESPONDING ...( ... CHANGING CONTROL ) ...For some additions, a mapping needs to be specified in the BDEF. For more information, see the ABAP Keyword Documentation topic.
The following example uses a BDEF derived type from the ABAP cheat sheets. It shows additions that do not require a type mapping to be specified.
"BDEF derived type
DATA derived_type TYPE STRUCTURE FOR UPDATE zdemo_abap_rap_ro_m.
"Other type
"For simplicity, the structure has the same component names
"and types to avoid further additions in the statement.
DATA: BEGIN OF some_other_type,
key_field TYPE i,
field1 TYPE c LENGTH 10,
field2 TYPE c LENGTH 10,
field3 TYPE i,
field4 TYPE i,
END OF some_other_type.
derived_type = VALUE #( key_field = 1
field1 = 'aaa'
field2 = 'bbb'
field3 = 2
field4 = 3
%control = VALUE #( key_field = if_abap_behv=>mk-on
field1 = if_abap_behv=>mk-off
field2 = if_abap_behv=>mk-on
field3 = if_abap_behv=>mk-on
field4 = if_abap_behv=>mk-off ) ).
*&---------------------------------------------------------------------*
*& USING CONTROL addition
*&---------------------------------------------------------------------*
"This addition respects the %control component of BDEF derived types, i.e.
"only those fields for which the %control field has been marked as enabled
"are respected by the mapping. A disabled %control field means that the
"mapping is not applied.
"In the example, components are marked as disabled in %control.
"Consequently, the field values are not assigned, and the type-specific
"initial values are used.
some_other_type = CORRESPONDING #( derived_type USING CONTROL ).
*KEY_FIELD FIELD1 FIELD2 FIELD3 FIELD4
*1 bbb 2 0
*&---------------------------------------------------------------------*
*& CHANGING CONTROL addition
*&---------------------------------------------------------------------*
"This variant fills the %control structure of a BDEF-derived type based on
"a non-BDEF-derived type that does not include control information.
"In the example, two components are not assigned (i.e. they remain initial).
"Consequently, when using the CORRESPONDING operator with CHANGING CONTROL,
"the %control values are marked as disabled, the others as enabled.
some_other_type = VALUE #( key_field = 4 field1 = 'ccc' field4 = 5 ).
derived_type = CORRESPONDING #( some_other_type CHANGING CONTROL ).
*%CID_REF KEY_FIELD FIELD1 FIELD2 FIELD3 FIELD4 %CONTROL
* 4 ccc 0 5 KEY_FIELD FIELD1 FIELD2 FIELD3 FIELD4
* 01 01 00 00 01The ABAP SQL statements INSERT, UPDATE, MODIFY, and DELETE offer the MAPPING FROM ENTITY addition to handle BDEF derived types.
*&---------------------------------------------------------------------*
*& INSERT
*&---------------------------------------------------------------------*
"Populating a BDEF derived type
DATA cr_der_type TYPE STRUCTURE FOR CREATE zdemo_abap_rap_ro_m.
"%control is not relevant in this example
cr_der_type = VALUE #( key_field = 1
field1 = 'aaa'
field2 = 'bbb'
field3 = 2
field4 = 3 ).
INSERT zdemo_abap_rapt1 FROM @cr_der_type MAPPING FROM ENTITY.
*KEY_FIELD FIELD1 FIELD2 FIELD3 FIELD4
*1 aaa bbb 2 3
*&---------------------------------------------------------------------*
*& MODIFY
*&---------------------------------------------------------------------*
cr_der_type = VALUE #( BASE cr_der_type
field1 = 'YYY'
field2 = 'ZZZ' ).
MODIFY zdemo_abap_rapt1 FROM @cr_der_type MAPPING FROM ENTITY.
*KEY_FIELD FIELD1 FIELD2 FIELD3 FIELD4
*1 YYY ZZZ 2 3
*&---------------------------------------------------------------------*
*& UPDATE with the INDICATORS SET STRUCTURE %control addition
*&---------------------------------------------------------------------*
"Populating a BDEF derived type
"%control is relevant in this example. Some %control values are enabled,
"some are not.
cr_der_type = VALUE #( key_field = 1
field1 = '###'
field2 = '...'
field3 = 100
field4 = 200
%control = VALUE #( key_field = if_abap_behv=>mk-on
field1 = if_abap_behv=>mk-on
field2 = if_abap_behv=>mk-off
field3 = if_abap_behv=>mk-off
field4 = if_abap_behv=>mk-on ) ).
UPDATE zdemo_abap_rapt1 FROM @cr_der_type
INDICATORS SET STRUCTURE %control MAPPING FROM ENTITY.
*KEY_FIELD FIELD1 FIELD2 FIELD3 FIELD4
*1 ### ZZZ 2 200
*&---------------------------------------------------------------------*
*& DELETE
*&---------------------------------------------------------------------*
DELETE zdemo_abap_rapt1 FROM @cr_der_type MAPPING FROM ENTITY.[!NOTE] More information and ABAP statements: Type Mapping for RAP
The focus is here on selected EML statements. These statements can be fairly long and various additions are possible. Find more information on the EML statements here.
The modifying operations covered include the standard operations (using the additions CREATE, CREATE BY, UPDATE, and DELETE) and non-standard operations (actions) using the addition EXECUTE. All EML statements for the mentioned operations begin with MODIFY. The following commented code snippets demonstrate the short and long form of EML MODIFY statements.
[!NOTE] Unlike reading operations, modifying operations are not enabled by default. You must make the respective notations in the BDEF: `` ... create; update; delete; action some_act; ... ``
MODIFY statement is used.FIELDS ( ... ) WITH addition. See more details in the documentation and below."Declaration of data objects using BDEF derived types
DATA: cr_tab TYPE TABLE FOR CREATE root_ent, "input derived type
mapped_resp TYPE RESPONSE FOR MAPPED root_ent, "response parameters
failed_resp TYPE RESPONSE FOR FAILED root_ent,
reported_resp TYPE RESPONSE FOR REPORTED root_ent.
"Input derived type for the EML statement is filled using the VALUE operator
"Assumption: key_field is the key field having type i,
"field1 and field2 are data fields with character-like data type.
"Specify %cid even if not used or of interest; it must be unique within a request
cr_tab = VALUE #(
( %cid = 'cid1' key_field = 1
field1 = 'A' field2 = 'B' )
( %cid = 'cid2'
"Just to demo %data/%key. You can specify fields with or without
"the derived type components
%data = VALUE #( %key-key_field = 2
field1 = 'C'
field2 = 'D' ) ) ).
"EML statement, short form
"root_ent must be the full name of the root entity, it is basically the name of the BDEF
MODIFY ENTITY root_ent
CREATE "determines the kind of operation
FIELDS ( key_field field1 field2 ) WITH cr_tab "Fields to be respected for the
"input derived type and the input
"derived type itself
MAPPED mapped_resp "mapping information
FAILED failed_resp "information on failures with instances
REPORTED reported_resp. "messages[!NOTE] - Addition FIELDS ( ... ) WITH:
This field selection option specifies which fields are to be respected for the operation. The derived type, i. e. an internal table containing the concrete RAP BO instance values, follows WITH. If a field is specified in the field list within the pair of parentheses after FIELDS, the %control flag for this field is automatically set to if_abap_behv=>mk-on. Likewise, if a field is not contained in the list, the flag in %control is set to if_abap_behv=>mk-off. Assume field2 is not specified in the list. The value for field2 will not be respected (even if a value is specified in the internal table). The initial value will be used for the field.
- Retrieving the responses and specifying the parameters is optional.
Assuming a data set with the value 2 for key_field already exists on the database for this BO, you should expect an entry for this particular instance in the failed_resp operand and potentially an error message in reported_resp, too. Nevertheless, especially in ABP implementations and depending on the context (in those methods you self-implement), you should implement and fill these parameters according to the RAP BO contract to meet the variety of implementation rules.
-%cidshould (or rather must) be provided even if you are not interested in its and subsequent operations do not require the reference. For an automatic provision of the%cidvalue, you can use theAUTO FILL CIDaddition in create operations.
MODIFY statement.FROM addition instead of FIELDS ( ... ) WITH. See more details in the documentation and below.MODIFY ENTITIES OF root_ent "full name of root entity
ENTITY root "root or child entity (alias name if available)
CREATE FROM "FROM as further field selection variant
VALUE #( ( %cid = 'cid' "Input derived type created inline
key_field = 3
field1 = 'E'
field2 = 'F'
%control = VALUE #( "Must be filled when using FROM
key_field = if_abap_behv=>mk-on
field1 = if_abap_behv=>mk-on
field2 = if_abap_behv=>mk-on ) ) )
MAPPED DATA(m) "Target variables declared inline
FAILED DATA(f)
REPORTED DATA(r).
"Note: You can use the AUTO FILL CID addition to fill %cid automatically. It is
"also possible in the short form.
MODIFY ENTITIES OF root_ent
ENTITY root
CREATE AUTO FILL CID WITH
VALUE #( ( key_field = 3
field1 = 'E'
field2 = 'F'
%control = VALUE #(
key_field = if_abap_behv=>mk-on
field1 = if_abap_behv=>mk-on
field2 = if_abap_behv=>mk-on ) ) )
MAPPED DATA(m2)
FAILED DATA(f2)
REPORTED DATA(r2).[!NOTE] - The entity specified after ENTITY can be either the root
entity itself or a child entity. If an alias is defined, the alias should be used.
- The addition FIELDS ( ... ) WITH from the previous
snippet is basically a shortcut for the addition FROM that is used here. When using FROM, the values of the %control structure must be specified explicitly.
- The BDEF derived types can also be created
inline as shown in the example using a constructor expression for the input derived type and with DATA or FINAL for the responses.
- The long form allows you to bundle several operations in one
statement, either different operations on the same entity (for example, deleting some instances and updating some others) or operations on different entities of the same RAP BO (for example, creating a root entity instance and related instances of a child entity in one EML request). Long and short forms are also available for other EML statements.
- TheSET FIELDS WITHaddition is available as another field specification option. However, it has limitations that you should be aware of. It can cause syntax warnings. Check the documentation. It is recommended that you useFIELDS ... WITHandFROM.
*&---------------------------------------------------------------------*
*& Short form of EML MODIFY statement
*&---------------------------------------------------------------------*
"The example code snippet uses data objects declared upfront instead of
"inline declarations.
DATA: upd_tab TYPE TABLE FOR UPDATE zdemo_abap_rap_ro_m,
failed_resp TYPE RESPONSE FOR FAILED zdemo_abap_rap_ro_m,
reported_resp TYPE RESPONSE FOR REPORTED zdemo_abap_rap_ro_m.
"Note:
"The BDEF derived type does not have a %cid component but %cid_ref
"to refer to an existing instance (its %cid value) within the same
"EML request. The example includes the reference to an existing
"instance using %cid_ref for demonstration purposes, commented out.
"The example does not include an actually referable instance. When
"there is no referable instance, a runtime error occurs.
upd_tab = VALUE #(
( key_field = 1 field1 = 'A' field2 = 'B' field3 = 1 field4 = 2 )
( key_field = 2 field1 = 'C' field2 = 'D' field3 = 3 field4 = 4 )
"( %cid_ref = `some_cid` field1 = 'E' field2 = 'F' field3 = 5 field4 = 6 )
).
"Note:
"- The statement includes the field specification option FIELDS ( ... ) WITH.
" The fields to be respected are included in the parentheses. For these,
" %control is flagged as if_abap_behv=>mk-on. The others, field3 and field4,
" are not specified. Therefore, %control is flagged as if_abap_behv=>mk-off
" for these fields.
"- Typically, the key fields are not included since changing them is ruled
" out in the example's BDEF: field ( readonly:update ) key_field;
"- The EML statement does not have the mapped response parameter. No
" new instance are created in update operations.
MODIFY ENTITY zdemo_abap_rap_ro_m
UPDATE
FIELDS ( field1 field2 ) WITH upd_tab
FAILED failed_resp
REPORTED reported_resp.
*&---------------------------------------------------------------------*
*& Long form of EML MODIFY statement
*&---------------------------------------------------------------------*
"Note:
"- The statement's operands are all declared inline.
"- The statement includes the field specification option FROM.
"- This specification option requires %control to be filled explicitly.
" Unlike the previous example, the update operation also respects
" field3 and field4, indicated by flagging all non-key components with
" if_abap_behv=>mk-on. As above, changing the key values is ruled out.
" Flagging key_field with if_abap_behv=>mk-on results in a runtime error.
"- See the excursion with specifying the %control component values.
" Applying the coding technique mentioned there (providing the corresponding
" values for all table lines outside of the inner parentheses), you can
" save the specification of code lines.
"- As above, an example with %cid_ref is included but commented out since
" the example does not inlcude a referable instance.
MODIFY ENTITIES OF zdemo_abap_rap_ro_m
ENTITY root
UPDATE
FROM VALUE #(
( key_field = 4 field1 = 'G' field2 = 'H' field3 = 7 field4 = 8
%control = VALUE #( key_field = if_abap_behv=>mk-off
field1 = if_abap_behv=>mk-off
field2 = if_abap_behv=>mk-on
field3 = if_abap_behv=>mk-on
field4 = if_abap_behv=>mk-on ) )
( key_field = 5 field1 = 'I' field2 = 'J' field3 = 9 field4 = 10
%control = VALUE #( key_field = if_abap_behv=>mk-off
field1 = if_abap_behv=>mk-on
field2 = if_abap_behv=>mk-on
field3 = if_abap_behv=>mk-on
field4 = if_abap_behv=>mk-on ) )
* ( %cid_ref = `another_cid` field1 = 'K' field2 = 'L' field3 = 11 field4 = 12
* %control = VALUE #( key_field = if_abap_behv=>mk-off
* field1 = if_abap_behv=>mk-on
* field2 = if_abap_behv=>mk-on
* field3 = if_abap_behv=>mk-on
* field4 = if_abap_behv=>mk-on ) )
)
FAILED DATA(f_resp)
REPORTED DATA(r_resp).*&---------------------------------------------------------------------*
*& Short form of EML MODIFY statement
*&---------------------------------------------------------------------*
"The example code snippet uses data objects declared upfront instead of
"inline declarations.
DATA: del_tab TYPE TABLE FOR DELETE zdemo_abap_rap_ro_m,
failed_response TYPE RESPONSE FOR FAILED zdemo_abap_rap_ro_m,
reported_response TYPE RESPONSE FOR REPORTED zdemo_abap_rap_ro_m.
"Note:
"The BDEF derived type only includes components to identify instances.
"This can be either referring to an existing existing using %cid_ref
"- its %cid value - within the same EML request, or the key. The example
"includes the reference to an existing instance using %cid_ref for
"demonstration purposes, commented out. The example does not include an
"actually referable instance. When there is no referable instance, a
"runtime error occurs.
del_tab = VALUE #(
( key_field = 1 )
( key_field = 2 )
"( %cid_ref = `some_cid` )
).
"Note:
"EML MODIFY staments for delete operations can only use the field
"specification option FROM.
MODIFY ENTITY zdemo_abap_rap_ro_m
DELETE
FROM del_tab
FAILED failed_response
REPORTED reported_response.
*&---------------------------------------------------------------------*
*& Long form of EML MODIFY statement
*&---------------------------------------------------------------------*
"Note:
"The statement's operands are all declared inline.
MODIFY ENTITIES OF zdemo_abap_rap_ro_m
ENTITY root
DELETE
FROM VALUE #(
( key_field = 4 )
( key_field = 5 )
"( %cid_ref = `another_cid` )
)
FAILED DATA(f_del_resp)
REPORTED DATA(r_del_resp).MODIFY ENTITIES OPERATIONS ....DATA: op_tab TYPE abp_behv_changes_tab,
create_root_tab TYPE TABLE FOR CREATE zdemo_abap_rap_ro_m,
update_root_tab TYPE TABLE FOR UPDATE zdemo_abap_rap_ro_m,
delete_root_tab TYPE TABLE FOR UPDATE zdemo_abap_rap_ro_m,
cba TYPE TABLE FOR CREATE zdemo_abap_rap_ro_m\_child,
update_child_tab TYPE TABLE FOR UPDATE zdemo_abap_rap_ch_m,
delete_child_tab TYPE TABLE FOR DELETE zdemo_abap_rap_ch_m.
create_root_tab = VALUE #(
( %cid = 'cid1'
key_field = 5
%control-key_field = if_abap_behv=>mk-on
field1 = 'a'
%control-field1 = if_abap_behv=>mk-on
field2 = 'b'
%control-field2 = if_abap_behv=>mk-on )
( %cid = 'cid2'
key_field = 6
%control-key_field = if_abap_behv=>mk-on
field1 = 'd'
%control-field1 = if_abap_behv=>mk-on
field2 = 'd'
%control-field2 = if_abap_behv=>mk-on )
( %cid = 'cid3'
key_field = 7
%control-key_field = if_abap_behv=>mk-on
field1 = 'e'
%control-field1 = if_abap_behv=>mk-on
field2 = 'f'
%control-field2 = if_abap_behv=>mk-on ) ).
update_root_tab = VALUE #(
( %cid_ref = 'cid2'
field1 = 'g'
%control-field1 = if_abap_behv=>mk-on
field2 = 'h'
%control-field2 = if_abap_behv=>mk-on ) ).
cba = VALUE #(
( %cid_ref = 'cid1'
%target = VALUE #( (
%cid = 'cid_cba1'
key_ch = 10
%control-key_ch = if_abap_behv=>mk-on
field_ch1 = 'i'
%control-field_ch1 = if_abap_behv=>mk-on
field_ch2 = 1
%control-field_ch2 = if_abap_behv=>mk-on
) ) )
( %cid_ref = 'cid2'
%target = VALUE #( (
%cid = 'cid_cba2'
key_ch = 20
%control-key_ch = if_abap_behv=>mk-on
field_ch1 = 'j'
%control-field_ch1 = if_abap_behv=>mk-on
field_ch2 = 2
%control-field_ch2 = if_abap_behv=>mk-on
) ) )
( %cid_ref = 'cid3'
%target = VALUE #( (
%cid = 'cid_cba3'
key_ch = 30
%control-key_ch = if_abap_behv=>mk-on
field_ch1 = 'k'
%control-field_ch1 = if_abap_behv=>mk-on
field_ch2 = 3
%control-field_ch2 = if_abap_behv=>mk-on
) ) ) ).
update_child_tab = VALUE #(
( key_field = 6
field_ch1 = 'l'
%control-field_ch1 = if_abap_behv=>mk-on
field_ch2 = 4
%control-field_ch2 = if_abap_behv=>mk-on ) ).
delete_root_tab = VALUE #( ( key_field = 7 ) ).
delete_child_tab = VALUE #( ( key_field = 7 ) ).
op_tab = VALUE #(
( op = if_abap_behv=>op-m-create
entity_name = 'ZDEMO_ABAP_RAP_RO_M'
instances = REF #( create_root_tab ) )
( op = if_abap_behv=>op-m-update
entity_name = 'ZDEMO_ABAP_RAP_RO_M'
instances = REF #( update_root_tab ) )
( op = if_abap_behv=>op-m-delete
entity_name = 'ZDEMO_ABAP_RAP_RO_M'
instances = REF #( delete_root_tab ) )
( op = if_abap_behv=>op-m-create_ba
entity_name = 'ZDEMO_ABAP_RAP_RO_M'
sub_name = '_CHILD'
instances = REF #( cba ) )
( op = if_abap_behv=>op-m-update
entity_name = 'ZDEMO_ABAP_RAP_CH_M'
instances = REF #( update_child_tab ) )
( op = if_abap_behv=>op-m-delete
entity_name = 'ZDEMO_ABAP_RAP_CH_M'
instances = REF #( delete_child_tab ) )
).
MODIFY ENTITIES OPERATIONS op_tab
MAPPED DATA(m)
FAILED DATA(f)
REPORTED DATA(r).MODIFY ... EXECUTE ...."Example snippet taken from the executable example
"The long form of the MODIFY statement is used. It includes
"a create operation and executes an action.
MODIFY ENTITIES OF zdemo_abap_rap_ro_m
ENTITY root
CREATE FIELDS ( key_field field1 field2 field3 field4 )
WITH VALUE #(
( %cid = 'cid_x2'
key_field = 7
field1 = 'ooo'
field2 = 'ppp'
field3 = 70
field4 = 71 ) )
EXECUTE multiply_by_2 FROM VALUE #(
"Executing action via %cid_ref
( %cid_ref = 'cid_x2' )
"Executing action via key
( key_field = 1 )
( key_field = 2 ) )
MAPPED DATA(mapped)
FAILED DATA(failed)
REPORTED DATA(reported).FROM addition, the %control values must be specified explicitly. VALUE constructor expressions. In this case, you can provide the corresponding values for all table lines outside of the inner parentheses, instead of individually specifying the values for each instance within the parentheses. %control component value is then assigned for all of the following table lines.MODIFY ENTITIES OF zdemo_abap_rap_ro_m
ENTITY root
CREATE FROM VALUE #(
%control-key_field = if_abap_behv=>mk-on
%control-field1 = if_abap_behv=>mk-on
%control-field2 = if_abap_behv=>mk-on
%control-field3 = if_abap_behv=>mk-on
%control-field4 = if_abap_behv=>mk-off
( %cid = 'cid1'
key_field = 1
field1 = 'aaa'
field2 = 'bbb'
field3 = 10
field4 = 100 )
( %cid = 'cid2'
key_field = 2
field1 = 'ccc'
field2 = 'ddd'
field3 = 20
field4 = 200 ) )
MAPPED DATA(m)
FAILED DATA(f)
REPORTED DATA(r).The following EML statement combines multiple operations in one EML request. It demonstrates the use of the BDEF derived type components %cid and %cid_ref.
%cid. FIELDS ( ... ) WITH addition which denotes that only this particular field should be updated. %cid_ref. %cid_ref exists, e. g. for an update operation. You can also make the reference using the unique key. DELETE can only be followed by the addition FROM. TYPE TABLE FOR DELETE) only has %cid_ref and the key as components.MODIFY ENTITIES OF root_ent
ENTITY root
CREATE FIELDS ( key_field field1 field2 ) WITH
VALUE #( ( %cid = 'cid4' key_field = 4
field1 = 'G' field2 = 'H' )
( %cid = 'cid5' key_field = 5
field1 = 'I' field2 = 'J' ) )
UPDATE FIELDS ( field2 ) WITH
VALUE #( ( %cid_ref = 'cid4' field2 = 'Z' ) )
DELETE FROM
VALUE #( ( %cid_ref = 'cid5' ) "Instance referenced via %cid_ref
( key_field = 9 ) ) "Instance referenced via the key
...The following code snippet shows a deep create.
composition [1..*] of root_ent as _child and key_field and key_field_child are the keys of the child view entity. %target enters the picture here which contains the target's primary key and data fields.MODIFY ENTITIES OF root_ent
ENTITY root_ent
CREATE FIELDS ( key_field field1 field2 ) WITH
VALUE #( ( %cid = 'cid6' key_field = 6
field1 = 'I' field2 = 'J' ) )
CREATE BY \_child
FIELDS ( key_field_child field1_child field2_child ) WITH
VALUE #( ( %cid_ref = 'cid6'
%target = VALUE #( ( %cid = 'cid_child_1'
key_field_child = 1
field1_child = 'aa'
field2_child = 'bb' )
( %cid = 'cid_child_2'
key_field_child = 2
field1_child = 'cc'
field2_child = 'dd' ) ) ) )
...EML statement requires the addition RESULT and an operand.
current status of instances in the transactional buffer which includes unsaved modifications on instances. If an instance is not yet available in the transactional buffer, the currently persisted data set is (automatically - in case of a managed scenario) read into the transactional buffer.
entity listed in a BDEF, i. e. there is no extra definition in the BDEF in contrast to, for example, create or update.
READ statement for reading instances from the root entity.
READ statements, the additions FIELDS ( ... ) WITH and FROM can also be used to specify the fields that you intend toread. Here, the addition ALL FIELDS WITH is available for reading all field values.
READ ENTITIES OF root_ent
ENTITY root_ent
ALL FIELDS WITH
VALUE #( ( key_field = 1 ) "Derived type TYPE TABLE FOR READ IMPORT only includes the keys
( key_field = 2 ) )
RESULT DATA(result)
FAILED DATA(f)
REPORTED DATA(r).LINK with which you can retrieve the keys of the source and target (i. e. the associated entity).
parent instance via the child, too.
"Read-by association operation: parent to child
READ ENTITIES OF root_ent
ENTITY root_ent
BY \_child
ALL FIELDS WITH VALUE #( ( key_field = 1 ) )
RESULT DATA(rba_res1)
LINK DATA(links1).
...
"Read-by association operation: child to parent
READ ENTITIES OF root_ent
ENTITY child_ent
BY \_parent
ALL FIELDS WITH VALUE #( ( key_field = 1 key_field_child = 1 ) )
RESULT DATA(rba_res2)
LINK DATA(links2).
...In addition to the short and long forms described above, various ABAP EML statements also have dynamic forms. Taking EML read operations as an example, the following code snippet shows a dynamic EML READ ENTITIES statement. The relevant syntax element is the OPERATIONS addition. The dynamic form allows the collection of read operations for multiple RAP BOs in one EML statement. For more information, see the ABAP keyword documentation and the comments in the snippet.
"The statement is taken from the executable example. The example has a
"root entity and a child entity. For both entities, RAP BO instances
"are to be read (read and read-by-association operation).
DATA:
"The following data object is the operand of the dynamic EML statement
"It is an internal table and has a special, RAP-specific type.
op_tab TYPE abp_behv_retrievals_tab,
"More data object declarations (internal tables typed with BDEF
"derived types) that are relevant for the EML statement.
"For both entities (root and child), RAP BO instances are to be
"read. The internal tables are used for components of the internal
"table op_tab further down.
read_dyn TYPE TABLE FOR READ IMPORT zdemo_abap_rap_ro_m,
read_dyn_result TYPE TABLE FOR READ RESULT zdemo_abap_rap_ro_m,
rba_dyn TYPE TABLE FOR READ IMPORT zdemo_abap_rap_ro_m\_child,
rba_dyn_result TYPE TABLE FOR READ RESULT zdemo_abap_rap_ro_m\_child,
rba_dyn_link TYPE TABLE FOR READ LINK zdemo_abap_rap_ro_m\_child.
"Filling the internal tables, i.e. which instances are to be read
"Root entity
"Example:
"- The key is comprised of the field 'key_field'. It is of type i.
"- The %control structure is filled, flagging those fields that
" are to be read. Flagging the key field is not required.
read_dyn = VALUE #(
( %key-key_field = 1
%control = VALUE #(
field1 = if_abap_behv=>mk-on
field2 = if_abap_behv=>mk-on
field3 = if_abap_behv=>mk-on
field4 = if_abap_behv=>mk-on ) )
( %key-key_field = 2
%control = VALUE #(
field1 = if_abap_behv=>mk-on
field2 = if_abap_behv=>mk-on
field3 = if_abap_behv=>mk-on
field4 = if_abap_behv=>mk-on ) ) ).
"Child entity
"Instances to be read for a read-by-association operation
"The shared key is 'key_field'.
rba_dyn = VALUE #(
( %key-key_field = 1
%control = VALUE #(
key_ch = if_abap_behv=>mk-on
field_ch1 = if_abap_behv=>mk-on
field_ch2 = if_abap_behv=>mk-on ) )
( %key-key_field = 2
%control = VALUE #(
key_ch = if_abap_behv=>mk-on
field_ch1 = if_abap_behv=>mk-on
field_ch2 = if_abap_behv=>mk-on ) ) ).
"Filling the internal table that is the operand of the
"dynamic EML statement
"This table has optional and mandatory components.
op_tab = VALUE #(
( "op: Specifies the operation to be executed; is mandatory;
" can be set with the predefined constants, e.g. OP-R-READ
" etc., of interface IF_ABAP_BEHV
op = if_abap_behv=>op-r-read
"entity_name: Specifies the name of the RAP BO entity for which
" the operation is executed; is mandatory
entity_name = 'ZDEMO_ABAP_RAP_RO_M'
"instances: Specifies a reference to an internal table holding
" the input keys; must be appropriately typed; is mandatory
instances = REF #( read_dyn )
"results: Specifies a reference to an internal table with the required
" BDEF derived type for the read results; is mandatory
results = REF #( read_dyn_result ) )
( op = if_abap_behv=>op-r-read_ba
entity_name = 'ZDEMO_ABAP_RAP_RO_M'
"sub_name: Only relevant for specifying association names in
" read-by-association operations; in that context, it is mandatory
sub_name = '_CHILD'
"full: Optional flag; specifies if all target instances are to be retrieved
full = abap_true
instances = REF #( rba_dyn )
results = REF #( rba_dyn_result )
"links: Reference to internal table holding the key pairs of the source and
" target
links = REF #( rba_dyn_link ) ) ).
READ ENTITIES OPERATIONS op_tab.WITH CHANGES provide access to accumulated change information for RAP BO instances within a RAP transaction.READ ENTITY IN LOCAL MODE ... WITH CHANGES ...READ ENTITIES OF ... IN LOCAL MODE ENTITY ... WITH CHANGES ...RESULT, the BDEF derived type TYPE TABLE FOR READ CHANGES is expected.%chg, which indicates the accumulated operation.IN LOCAL MODE%control structure components in the read result indicate which fields have changed, but only for those components where the %chg value is either if_abap_behv=>cop-create, if_abap_behv=>cop-update, or if_abap_behv=>cop-recreate. In all other cases, the %control component value remains initial.WITH CHANGES cannot be specified. The functionality of WITH CHANGES is implemented in dynamic ABAP EML READ statements by setting the full component of the statement's operand to if_abap_behv=>typekind-result_chg.Example statements
"Short form
DATA read_changes TYPE TABLE FOR READ CHANGES demo_rap_entity.
READ ENTITY IN LOCAL MODE demo_rap_entity
WITH CHANGES
ALL FIELDS WITH CORRESPONDING #( keys )
RESULT read_changes
FAILED failed.
"Dynamic form
DATA: op_tab TYPE abp_behv_retrievals_tab,
read_dyn TYPE TABLE FOR READ IMPORT demo_rap_entity,
read_dyn_result TYPE TABLE FOR READ CHANGES demo_rap_entity,
entity TYPE abp_entity_name VALUE 'DEMO_RAP_ENTITY'.
read_dyn = VALUE #( FOR wa IN keys (
%key-key_field = wa-key_field
%control-field1 = if_abap_behv=>mk-on
%control-field2 = if_abap_behv=>mk-on
%control-field3 = if_abap_behv=>mk-on
%control-field4 = if_abap_behv=>mk-on ) ).
op_tab = VALUE #( (
op = if_abap_behv=>op-r-read
entity_name = entity
full = if_abap_behv=>typekind-result_chg
instances = REF #( read_dyn )
results = REF #( read_dyn_result ) ) ).
READ ENTITIES IN LOCAL MODE OPERATIONS op_tab FAILED DATA(f).ENTITIES](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcommit_entities.htm) statement triggers the RAP save sequence. Without such a statement, the modified RAP BO instances that are available in the transactional buffer are not persisted to the database. In case of a natively supported RAP scenario (for example, when using OData), the COMMIT ENTITIES` request is executed automatically.
COMMIT ENTITIES implicitly includes [`COMMITWORK`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcommit.htm).
COMMIT ENTITIES statements cannot be usedin behavior implementations.
in the ABAP Keyword Documentation here. They deal with different variants of how to handle RAP responses, among others.
COMMIT ENTITIES statements set the system fieldsy-subrc. When using COMMIT ENTITIES, it is not guaranteed that COMMIT WORK is carried out successfully. Hence, you should include a check for sy-subrc after COMMIT ENTITIES so that you can react to failures accordingly.
| Variant/Addition | Notes |
|
Short form of |
The following snippet shows a create operation. This operation has only an impact on the database with the |
|
Long form of |
The long syntax form includes the retrieval of information for one or more RAP BO entities. Root entities must be specified. |
|
Dynamic form of |
The dynamic syntax form allows you to retrieve RAP responses from RAP saver methods by dynamically specifying one or more RAP BO root entities. |
|
Specifying a commit scope |
|
|
Simulating a commit |
|
ROLLBACK ENTITIES statement rolls back all changes of the current RAP transaction.cleanup method) and locks.cleanup method must include an appropriate implementation to clear the transactional buffer.COMMIT ENTITIES, in natively supported RAP scenarios, such as an SAP Fiori application using OData, the ROLLBACK ENTITIES call is implicitly and automatically performed by the RAP runtime engine.The following example demonstrates the effect of ROLLBACK ENTITIES. In the second loop pass, ROLLBACK ENTITIES clears the transactional buffer, leaving nothing to commit. Therefore, the assertions are also true for the second loop.
DELETE FROM zdemo_abap_rapt1.
DO 2 TIMES.
MODIFY ENTITIES OF zdemo_abap_rap_ro_m
ENTITY root
CREATE FIELDS ( key_field )
AUTO FILL CID WITH VALUE #( ( key_field = sy-index ) )
MAPPED DATA(m1)
FAILED DATA(f1)
REPORTED DATA(r1).
IF sy-index = 2.
ROLLBACK ENTITIES.
ENDIF.
COMMIT ENTITIES.
IF sy-subrc <> 0.
...
ENDIF.
SELECT FROM zdemo_abap_rapt1
FIELDS key_field
ORDER BY key_field
INTO TABLE @DATA(tab).
ASSERT lines( tab ) = 1.
ASSERT tab[ 1 ]-key_field = 1.
ENDDO.GET PERMISSIONS statements, you can retrieve information about these permissions.GET PERMISSIONS offers multiple (optional) additions and syntax variants. GET PERMISSIONS, specifying an only clause. The ONLY GLOBAL addition ensures the result includes only global authorization, global and static feature control.GET PERMISSIONS example statement works with a data object having a structured BDEF derived type (after REQUEST), not a tabular BDEF derived type.DATA request TYPE STRUCTURE FOR PERMISSIONS REQUEST zdemo_abap_rap_ro_m.
request = VALUE #(
%create = if_abap_behv=>mk-on
%update = if_abap_behv=>mk-on
%delete = if_abap_behv=>mk-on
%field-key_field = if_abap_behv=>mk-on
%field-field1 = if_abap_behv=>mk-on
%field-field2 = if_abap_behv=>mk-on
%field-field3 = if_abap_behv=>mk-on
%field-field4 = if_abap_behv=>mk-on ).
GET PERMISSIONS ONLY GLOBAL ENTITY zdemo_abap_rap_ro_m
REQUEST request
RESULT DATA(result)
FAILED DATA(failed)
REPORTED DATA(reported).SET LOCKS statements to establish enqueue locks for RAP BO instances. This will prevent concurrent modifications.SET LOCKS ENTITY ...): Locks instances of a single RAP BO entity.SET LOCKS OF ...): Locks instances of multiple RAP BO entities in a CDS composition tree.SET LOCKS locks_tab ...): Collects instances of multiple RAP BO entities.TYPE TABLE FOR KEY OF, which is an internal table containing instance key values. The dynamic form uses an internal table of type ABP_BEHV_LOCKS_TAB.Example code snippet illustrating all forms:
DATA key_tab TYPE TABLE FOR KEY OF zdemo_abap_rap_ro_u.
key_tab = VALUE #( ( key_field = 1 )
( key_field = 2 ) ).
"Short form
SET LOCKS ENTITY zdemo_abap_rap_ro_u
FROM key_tab
FAILED DATA(f_short).
"Long form
"The statements specifies the key table inline.
SET LOCKS OF zdemo_abap_rap_ro_u
ENTITY root FROM VALUE #( ( key_field = 1 ) )
ENTITY child FROM VALUE #( ( key_field = 2 ) )
FAILED DATA(f_long)
REPORTED DATA(r_long).
"Dynamic form
DATA root_keys TYPE TABLE FOR KEY OF zdemo_abap_rap_ro_u.
DATA child_keys TYPE TABLE FOR KEY OF zdemo_abap_rap_ch_u.
root_keys = VALUE #( ( key_field = 1 ) ).
child_keys = VALUE #( ( key_field = 2 )
( key_field = 3 ) ).
"Populating the lock table that is of type abp_behv_locks_tab
"Components:
"- entity_name: Name of RAP BO entity in capital letters
"- instances: Reference to an internal table typed with the derived type TYPE TABLE FOR KEY OF
DATA(locks_tab) = VALUE abp_behv_locks_tab(
( entity_name = 'ZDEMO_ABAP_RAP_RO_U' instances = REF #( root_keys ) )
( entity_name = 'ZDEMO_ABAP_RAP_CH_U' instances = REF #( child_keys ) ) ).
SET LOCKS locks_tab FAILED DATA(f_dyn)
REPORTED DATA(r_dyn_).The code in the collapsible section illustrates the effect of a SET LOCKS statement using artifacts from the ABAP cheat sheet repository.
🟢 Click to expand for example code
SET LOCKS statement.if_oo_adt_classrun interface. As a prerequisite, the ABAP cheat sheet repository has been imported into the system.SET LOCKS statement (in its short form) to lock two instances (key fields with value 1 and 2).ASSERT statement is included to set a breakpoint.CLASS zcl_class1 DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_class1 IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
DELETE FROM zdemo_abap_rapt1.
MODIFY zdemo_abap_rapt1 FROM TABLE @( VALUE #( ( key_field = 1 )
( key_field = 2 )
( key_field = 3 )
( key_field = 4 ) ) ).
DATA key_tab TYPE TABLE FOR KEY OF zdemo_abap_rap_ro_u.
key_tab = VALUE #(
( key_field = 1 )
( key_field = 2 ) ).
SET LOCKS ENTITY zdemo_abap_rap_ro_u
FROM key_tab
FAILED DATA(f)
REPORTED DATA(r).
ASSERT 1 = 1.
ENDMETHOD.
ENDCLASS.cl_abap_lock_object_factory class to enqueue instances.SET LOCKS statement.cl_abap_lock_object_factory class calls include adding information to the enq string table, and the failed response parameter f is specified for the SET LOCKS statement.CLASS zcl_class2 DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_class2 IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
DATA key_tab TYPE TABLE FOR KEY OF zdemo_abap_rap_ro_u.
key_tab = VALUE #( ( key_field = 1 )
( key_field = 2 )
( key_field = 3 )
( key_field = 4 ) ).
DATA enq TYPE string_table.
TRY.
DATA(lo_lock) = cl_abap_lock_object_factory=>get_instance( iv_name = 'EZDEMO_ABAP_LOCK' ).
LOOP AT key_tab REFERENCE INTO DATA(lr_key).
APPEND |key_field = { lr_key->key_field }| TO enq.
TRY.
lo_lock->enqueue( it_parameter = VALUE #(
( name = 'KEY_FIELD' value = REF #( lr_key->key_field ) ) ) ).
APPEND | - Enqueue ok| TO enq.
CATCH cx_abap_foreign_lock INTO DATA(err_foreign_lock).
APPEND | - { err_foreign_lock->get_text( ) }| TO enq.
CATCH cx_abap_lock_failure INTO DATA(err_lock_failure).
APPEND | - { err_lock_failure->get_text( ) }| TO enq.
ENDTRY.
ENDLOOP.
CATCH cx_abap_lock_failure INTO err_lock_failure.
APPEND err_lock_failure->get_text( ) TO enq.
ENDTRY.
out->write( enq ).
SET LOCKS ENTITY zdemo_abap_rap_ro_u
FROM key_tab
FAILED DATA(f).
out->write( f ).
ENDMETHOD.
ENDCLASS.ASSERT statement. SET LOCKS statement in class 1 locks two instances (1 and 2) out of four. Consequently, the cl_abap_lock_object_factory calls and the additional SET LOCKS statement in class 2 should generate errors for attempting to lock instances with key values 1 and 2, since they are already locked. enq string table should contain the following entries, and the failed response parameter f should have two entries for 1 and 2 with the failure cause locked. key_field = 1
- Object is locked by user ...
key_field = 2
- Object is locked by user ...
key_field = 3
- Enqueue ok
key_field = 4
- Enqueue ok RAISE ENTITY EVENT statements, typically in the save phase. event specifications are available in the BDEF (e.g. ... event some_evt; ...). For more details, refer to the BDL documentation.CL_ABAP_BEHAVIOR_EVENT_HANDLER can be implemented in the CCIMP include of a RAP event handler class.*&---------------------------------------------------------------------*
*& Syntax for the declaration part of a global RAP event handler class
*&---------------------------------------------------------------------*
CLASS cl_event_handler DEFINITION PUBLIC FOR EVENTS OF some_bdef.
...
ENDCLASS.
*&---------------------------------------------------------------------*
*& Syntax for the declaration part of a local event handler class
*& in the CCIMP include of a RAP event handler class
*&---------------------------------------------------------------------*
CLASS lhe_event DEFINITION INHERITING FROM cl_abap_behavior_event_handler.
...
ENDCLASS.
*&---------------------------------------------------------------------*
*& RAP event handler method definition
*&---------------------------------------------------------------------*
"Notes:
"- Must be defined as instance methods in the private visibility section.
"- The input parameter par is an internal table of type TYPE TABLE FOR EVENT.
"- This type includes the keys of RAP BO instances (and %param, if the event
" is specified with a parameter in the BDEF)
"- The methods do not contain RAP response parameters.
METHODS meth FOR ENTITY EVENT par FOR some_bdef~some_evt.
*&---------------------------------------------------------------------*
*& RAISE ENTITY EVENT statement in an ABP, e.g. the save_modified method
*& in managed scenarios with additional save
*&---------------------------------------------------------------------*
...
CLASS lsc IMPLEMENTATION.
METHOD save_modified.
"Assumption: An event is specified for create operations in the BDEF as follows
"event created;
IF create-some_bdef IS NOT INITIAL.
RAISE ENTITY EVENT some_bdef~created
FROM VALUE #( FOR <cr> IN create-root ( %key = VALUE #( some_key = <cr>-some_key ) ) ).
ENDIF.
"Assumption: An event is specified for delete operations in the BDEF as follows
"event deleted parameter some_abstract_entity;
"The abstract entity has two parameters, for example, with which additional
"information can be passed.
IF delete-some_bdef IS NOT INITIAL.
RAISE ENTITY EVENT some_bdef~deleted
FROM VALUE #( FOR <del> IN delete-some_bdef (
%key = VALUE #( some_key = <del>-some_key )
%param = VALUE #( par_a = '01'
par_b = 'Item deleted' ) ) ).
ENDIF.
ENDMETHOD.
ENDCLASS.There are a special additions when using EML in behavior pools.
IN LOCAL MODE addition to ABAP EML READ and MODIFY statements can be used to suppress feature controls, authorization checks, and prechecks.booking status of a trip on a UI. In the BDEF, this field is specified as read-only. Hence, it cannot be modified by a user on the UI. However, there is a button on the UI to book the trip. This button might trigger an action to book the trip so that the value of the field changes from open to booked. To enable this, the underlying handler method for the modify operation with the action to be executed has the addition IN LOCAL MODE that ignores the feature control.
Syntax:
MODIFY ENTITIES OF root_ent IN LOCAL MODE
ENTITY root
EXECUTE book
FROM action_tab
...MODIFY statements include a special syntax variant used only in the context of projections: MODIFY AUGMENTING ENTITY|ENTITIES.AUGMENTING addition only in RAP BO providers.RELATING addition in this context. This is relevant if the augmented request contains instances not in the original request. It establishes a relationship between the new instances and the original ones in a relationship table to associate potential responses.MODIFY AUGMENTING ENTITY some_bdef
UPDATE FROM ...
"relates_tab is of type abp_behv_relating_tab
MODIFY AUGMENTING ENTITY some_bdef
UPDATE FROM ... RELATING TO some_instances BY relates_tab.The following bullet points outline important aspects regarding keys and identifying RAP BO instances in ABAP EML statements.
Why is it important?
key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenprimary_key_glosry.htm "Glossary Entry") of a RAP BO entity instance is composed of one or more key fields.
key in the underlying CDS view entity of the RAP BO.
persistent database table, the saving of a RAP BO instance is rejected because of a duplicate primary key.
How can a RAP BO instance be uniquely identified?
or RAP content identifier or both of them.
components.
component groups are available to summarize the components and make them addressable via one single name.
%key:Contains the primary key fields of a RAP BO instance
%tky:Specifies the transactional key. Comprises %key (and, thus, the primary key fields of a RAP BO instance) and more components that are relevant to uniquely identify a RAP BO instance. Among them, %pid (relevant for late numbering scenarios) and the draft indicator %is_draft (relevant for draft scenarios). In non-late numbering or non-draft scenarios, these extra components are just blank. However, it is recommended that you use %tky in all scenarios since it simplifies a possible later switch, for example, to a draft scenario. In doing so, lots of adaptations to the code regarding the keys and the inclusion of %is_draft can be avoided.
%cid which is a string of type ABP_BEHV_CID to define a content ID.
in RAP create operations, especially where no primary key exists for the particular instance.
%cid_ref (which has the same value as %cid), for example, in RAP operations using CREATE BY, UPDATEand DELETE, as well as actions with EXECUTE).
%pid for late numbering scenarios, %cid (and %cid_ref) are only available on a short-term basis for the current ABAP EML request within the RAP interaction phase in one RAP transaction.
%cid even if there are no further operations referring to it.entity instances are given their final key only shortly before saving in the database, i. e. you deal with preliminary keys in the RAP interaction phase and the early phase of the RAP save sequence.
%key to hold the preliminarykeys or use a preliminary ID in the dedicated component %pid which is of type ABP_BEHV_PID and only available in late numbering scenarios.
numbering scenarios, you can use either %key or %pid or both of them. In any case, the use of %tky is handy because it includes both components. You must ensure that %tky in total uniquely identifies the instances.
%pky. %pky contains %pid and %key in late numbering scenarios. In non-late numbering scenarios, it just contains %key. %pky itself is contained in %tky. There are contexts, for example, particular actions, where %tky is not available but %pky is. This way, there is still the option to summarize %pid and %key in one component group in the absence of %tky.General rule: A RAP BO instance must - where available - always be uniquely identifiable by its transactional key (%tky) for internal processing during the RAP interaction phase. %tky always contains all relevant components for the chosen scenario.
%tky whenever possible. wa-%tky = wa-%key. Such an assignment should also be avoided when both component groups have an identical scope in terms of components (e.g. %tky and %key in non-late-numbering and non-draft scenarios).wa_root-%tky = wa_child-%tky. In this case, adding more components later may cause syntax errors for an assignment that worked previously.CORRESPONDING operator can be used to ensure type compatibility in assignments to key component groups: ... %tky = CORRESPONDING #( wa-%tky ) ...
... %key = CORRESPONDING #( wa-%key ) ...
... %pky = CORRESPONDING #( wa-%pky ) ......wa1_root-%tky = wa2_root-%tky ...). The use of the CORRESPONDING operator is unnecessary and less performant. This is true, for example, for key component group assignments in the context of RAP response parameters failed and reported.RAP numbering
fields depending on when (early in the RAP interaction phase or late in the RAP save sequence) and by whom (RAP BO consumer, behavior pool, or framework) the primary key values are set.
The final key values are assigned during a RAP create operation in the interaction phase.
The final key values are assigned during the RAP save sequence (and here only in the RAP saver method adjust_numbers).
08_EML_ABAP_for_RAP.md。版权归原作者所有。