Skip to content

Lesson 12 Companion — EML and RAP Transactions ​

This companion supports:

text
Lesson 12 — EML and the RAP Transactional Buffer

It contains the deeper explanations and complete reference code for the Reservation EML consumer.


1. Lesson 12 architecture ​

The complete path is now:

text
ZCL_RESV_EML_###
        ↓
       EML
        ↓
ZR_RESERVATION_###
        ↓
Behavior Definition
        ↓
Managed RAP Runtime
        ↓
ZRESV_###

The key change from Lesson 9 is that the consumer no longer performs persistence writes directly.


2. EML consumption vs behavior implementation ​

EML appears in two broad situations.

External consumption/test scenario ​

Example:

text
ZCL_RESV_EML_###

This class is outside the Behavior Pool and consumes the BO contract normally.

Local BO implementation scenario ​

Inside a Behavior Pool, RAP implementation code may also use EML to work with the same or related BOs.

Access to the pool's own BO can use:

abap
IN LOCAL MODE

This addition is not available when consuming another BO.

Lesson 12 is the first scenario, so do not add IN LOCAL MODE.


3. Long-form EML vocabulary ​

The course uses forms such as:

abap
READ ENTITIES OF <root>
  ENTITY <alias>
    ...

and:

abap
MODIFY ENTITIES OF <root>
  ENTITY <alias>
    CREATE ...

Read:

text
OF <root>
=
which RAP Business Object?

ENTITY <alias>
=
which entity inside that BO?

For this BO:

text
root entity = ZR_RESERVATION_###
alias       = Reservation

4. Why EML is strongly typed ​

The Behavior Definition and CDS model generate BDEF-derived ABAP types.

This lets EML know about:

text
entity keys
fields
operations
control information
transactional identifiers
response structures

That is why ADT can catch many EML mistakes during syntax checking.


5. Useful BDEF-derived type syntax ​

You will increasingly see types such as:

abap
TYPE TABLE FOR CREATE ZR_Reservation_###
TYPE TABLE FOR UPDATE ZR_Reservation_###
TYPE TABLE FOR DELETE ZR_Reservation_###
TYPE TABLE FOR READ RESULT ZR_Reservation_###

You do not need to declare all of them explicitly in Lesson 12 because inline declarations are sufficient.

But recognize that the EML request/response structures are derived from the BO definition.


6. %cid ​

%cid means:

text
content identifier

It is a preliminary consumer-provided identifier for a create request.

Example:

abap
%cid = 'RES_A'

It is useful before the consumer knows the final technical key.


7. Managed early numbering ​

Lesson 11 declared:

abap
field ( numbering : managed, readonly ) Uuid;

For a managed UUID key, RAP assigns the UUID during the CREATE request.

This is:

text
managed
internal
early numbering

The key becomes available before the final save.

That is why the same transaction can continue working with the new instance.


8. MAPPED ​

For create operations involving generated keys, MAPPED connects preliminary identifiers to the generated identity.

Conceptually:

text
%cid = RES_A
     ↓
managed numbering
     ↓
Uuid = <generated RAW16 UUID>

The generated mapping is returned under the entity component:

text
mapped_create-reservation

A robust lookup is:

abap
DATA(mapped_a) = mapped_create-reservation[ %cid = 'RES_A' ].
DATA(uuid_a)   = mapped_a-Uuid.

Do the same for:

text
RES_B

This is safer than assuming a particular row order.


9. FAILED ​

FAILED identifies instances for which requested RAP processing failed.

The response is BO/entity structured.

Later it can tell you that an operation failed because of reasons such as:

text
not found
unauthorized
disabled operation
validation failure
conflict

Lesson 12 mainly checks whether it is empty.

Lesson 13 will intentionally produce failures.


10. REPORTED ​

REPORTED carries information reported by RAP processing.

Later this includes business messages with concepts such as:

text
severity
message text
affected entity
field markers
state area

For Lesson 12, a quiet/empty REPORTED structure is normal.


11. Early vs late responses ​

A useful mental model is:

text
MODIFY ENTITIES
      ↓
interaction-phase responses

COMMIT ENTITIES
      ↓
save-phase responses

The exact RAP internals are richer than this, but this distinction prepares students well for validations.


12. The transactional buffer ​

A RAP transaction is not simply a sequence of independent SQL statements.

During the interaction phase:

text
consumer requests modifications
        ↓
RAP processes them
        ↓
working state exists in transactional buffer

Other EML operations in the same RAP transaction can work with that state.

The save boundary comes later.


13. Read-your-own-changes behavior ​

A powerful demonstration is:

text
persistent Status = N

MODIFY ENTITIES UPDATE Status = C

READ ENTITIES before commit
→ sees C

ROLLBACK ENTITIES

READ ENTITIES again
→ sees N

This proves the distinction between:

text
current RAP transaction state

and:

text
persisted database state

14. COMMIT ENTITIES ​

For an external EML test/consumer scenario:

abap
COMMIT ENTITIES.

triggers the save sequence for all BOs changed in the current transaction. A successful save ends the transaction. If a validation rejects the save, no part of that transaction is committed; the consumer must correct the buffered state or roll it back.

A more informative form is:

abap
COMMIT ENTITIES
  RESPONSE OF ZR_Reservation_###
    FAILED DATA(failed_commit)
    REPORTED DATA(reported_commit).

This allows the consumer to inspect save-phase responses.


15. COMMIT ENTITIES and sy-subrc ​

Immediately after the commit, capture:

abap
DATA(commit_subrc) = sy-subrc.

Then inspect the captured value along with FAILED and REPORTED:

Return codeMeaning
0Save completed successfully.
4Early save phase failed, for example an on-save validation. Buffered work has not been persisted.
8Late save failure in scenarios that support returning such failures. An explicit rollback is required before further work.

In this course's test classes, output the responses, execute ROLLBACK ENTITIES, and stop whenever a commit fails. Capture the code before further operations so it still describes that commit. See SAP's EML transaction reference and LUW guidance.

Do not use:

text
sy-dbcnt

as though the RAP transaction were one SQL DML statement.


16. ROLLBACK ENTITIES ​

Use:

abap
ROLLBACK ENTITIES.

to discard changes of the current RAP transaction and reset the transactional buffer.

It is the RAP-specific rollback statement for this consumer scenario.


17. Why rollback should be taught before validations ​

Without rollback, students can mistakenly think:

text
MODIFY ENTITIES
=
permanent database change

The rollback experiment establishes the correct transaction mental model before Lesson 13 introduces business-rule failures.


18. CREATE reference ​

abap
MODIFY ENTITIES OF ZR_Reservation_###
  ENTITY Reservation
    CREATE FIELDS (
      ReservationNo
      CustomerName
      CustomerEmail
      WorkshopCode
      ReservationDate
      Status
      Fee
      CurrencyCode
      Notes )
    WITH VALUE #(
      ( %cid            = 'RES_A'
        ReservationNo   = '92000001'
        CustomerName    = 'EML Student A'
        CustomerEmail   = 'student.a@example.com'
        WorkshopCode    = 'RAP101'
        ReservationDate = cl_abap_context_info=>get_system_date( )
        Status           = 'N'
        Fee              = '150.00'
        CurrencyCode     = 'EUR'
        Notes            = 'Created with EML' )
      ( %cid            = 'RES_B'
        ReservationNo   = '92000002'
        CustomerName    = 'EML Student B'
        CustomerEmail   = 'student.b@example.com'
        WorkshopCode    = 'RAP101'
        ReservationDate = cl_abap_context_info=>get_system_date( )
        Status           = 'N'
        Fee              = '175.00'
        CurrencyCode     = 'EUR'
        Notes            = 'Delete demonstration' ) )
  MAPPED DATA(mapped_create)
  FAILED DATA(failed_create)
  REPORTED DATA(reported_create).

19. READ reference ​

abap
READ ENTITIES OF ZR_Reservation_###
  ENTITY Reservation
    ALL FIELDS
    WITH VALUE #( ( Uuid = uuid_a ) )
  RESULT DATA(reservations)
  FAILED DATA(failed_read).

The WITH table supplies the identity of the instance to read.


20. UPDATE reference ​

abap
MODIFY ENTITIES OF ZR_Reservation_###
  ENTITY Reservation
    UPDATE FIELDS ( Status Notes )
    WITH VALUE #(
      ( Uuid   = uuid_a
        Status = 'C'
        Notes  = 'Confirmed through EML' ) )
  FAILED DATA(failed_update)
  REPORTED DATA(reported_update).

The key identifies the target.

The FIELDS list identifies the business fields the request intends to update.


21. DELETE reference ​

abap
MODIFY ENTITIES OF ZR_Reservation_###
  ENTITY Reservation
    DELETE FROM VALUE #( ( Uuid = uuid_b ) )
  FAILED DATA(failed_delete)
  REPORTED DATA(reported_delete).

No direct SQL delete is needed.


22. Why the consumer does not provide administrative fields ​

The BDEF defines them as read-only.

The consumer should not send:

text
LocalCreatedBy
LocalCreatedAt
LocalLastChangedBy
LocalLastChangedAt
LastChangedAt

on a normal create/update request.

Managed RAP maintains the lifecycle fields according to the configured managed model.


23. Why the consumer does not provide Uuid ​

The BDEF says:

abap
field ( numbering : managed, readonly ) Uuid;

Therefore:

text
consumer provides %cid
RAP provides Uuid

This is a concrete runtime payoff from Lesson 11.


24. Repeatable training reset ​

A fixed business number is useful for classroom inspection, but it means an earlier run may already have created the demonstration rows.

Do not solve this with:

abap
DELETE FROM zresv_###.

A safe training reset is:

  1. query the root CDS only to discover UUIDs of the reserved demonstration rows;
  2. delete those UUIDs through EML;
  3. commit the cleanup.

Example:

abap
SELECT FROM ZR_Reservation_###
  FIELDS Uuid
  WHERE ReservationNo = '92000001'
     OR ReservationNo = '92000002'
  INTO TABLE @DATA(old_demo_keys).

IF old_demo_keys IS NOT INITIAL.

  MODIFY ENTITIES OF ZR_Reservation_###
    ENTITY Reservation
      DELETE FROM VALUE #(
        FOR old_key IN old_demo_keys
        ( Uuid = old_key-Uuid ) )
    FAILED DATA(failed_cleanup)
    REPORTED DATA(reported_cleanup).

  IF failed_cleanup IS NOT INITIAL.
    out->write( failed_cleanup ).
    out->write( reported_cleanup ).
    ROLLBACK ENTITIES.
    RETURN.
  ENDIF.

  COMMIT ENTITIES
    RESPONSE OF ZR_Reservation_###
      FAILED DATA(failed_cleanup_commit)
      REPORTED DATA(reported_cleanup_commit).
  DATA(cleanup_commit_subrc) = sy-subrc.

  IF cleanup_commit_subrc <> 0 OR failed_cleanup_commit IS NOT INITIAL.
    out->write( failed_cleanup_commit ).
    out->write( reported_cleanup_commit ).
    ROLLBACK ENTITIES.
    RETURN.
  ENDIF.

ENDIF.

This is training setup logic, not normal business application logic.

All modifications still go through the BO.


25. Why a CDS SELECT is acceptable in that reset ​

The rule after RAP is primarily:

Do not bypass BO behavior for business modifications.

A read-only query against the CDS root to discover technical keys for a classroom reset does not perform a persistence modification.

The actual delete still goes through:

text
EML

Do not turn this exception into the normal consumer architecture.


26. Complete reference consumer ​

The following source shows a repeatable classroom demonstration.

abap
CLASS zcl_resv_eml_### DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC.

  PUBLIC SECTION.
    INTERFACES if_oo_adt_classrun.

ENDCLASS.

CLASS zcl_resv_eml_### IMPLEMENTATION.

  METHOD if_oo_adt_classrun~main.

    out->write( 'Lesson 12 - Reservation EML' ).

    " ------------------------------------------------------------
    " 0. Repeatable training cleanup
    " ------------------------------------------------------------
    SELECT FROM ZR_Reservation_###
      FIELDS Uuid
      WHERE ReservationNo = '92000001'
         OR ReservationNo = '92000002'
      INTO TABLE @DATA(old_demo_keys).

    IF old_demo_keys IS NOT INITIAL.

      MODIFY ENTITIES OF ZR_Reservation_###
        ENTITY Reservation
          DELETE FROM VALUE #(
            FOR old_key IN old_demo_keys
            ( Uuid = old_key-Uuid ) )
        FAILED DATA(failed_cleanup)
        REPORTED DATA(reported_cleanup).

      out->write( failed_cleanup ).
      out->write( reported_cleanup ).

      IF failed_cleanup IS NOT INITIAL.
        ROLLBACK ENTITIES.
        out->write( 'Cleanup failed. Demo stopped.' ).
        RETURN.
      ENDIF.

      COMMIT ENTITIES
        RESPONSE OF ZR_Reservation_###
          FAILED DATA(failed_cleanup_commit)
          REPORTED DATA(reported_cleanup_commit).
      DATA(cleanup_commit_subrc) = sy-subrc.

      IF cleanup_commit_subrc <> 0 OR failed_cleanup_commit IS NOT INITIAL.
        out->write( failed_cleanup_commit ).
        out->write( reported_cleanup_commit ).
        ROLLBACK ENTITIES.
        out->write( 'Cleanup commit failed. Demo stopped.' ).
        RETURN.
      ENDIF.

    ENDIF.

    " ------------------------------------------------------------
    " 1. CREATE two Reservations
    " ------------------------------------------------------------
    MODIFY ENTITIES OF ZR_Reservation_###
      ENTITY Reservation
        CREATE FIELDS (
          ReservationNo
          CustomerName
          CustomerEmail
          WorkshopCode
          ReservationDate
          Status
          Fee
          CurrencyCode
          Notes )
        WITH VALUE #(
          ( %cid            = 'RES_A'
            ReservationNo   = '92000001'
            CustomerName    = 'EML Student A'
            CustomerEmail   = 'student.a@example.com'
            WorkshopCode    = 'RAP101'
            ReservationDate = cl_abap_context_info=>get_system_date( )
            Status           = 'N'
            Fee              = '150.00'
            CurrencyCode     = 'EUR'
            Notes            = 'Created with EML' )

          ( %cid            = 'RES_B'
            ReservationNo   = '92000002'
            CustomerName    = 'EML Student B'
            CustomerEmail   = 'student.b@example.com'
            WorkshopCode    = 'RAP101'
            ReservationDate = cl_abap_context_info=>get_system_date( )
            Status           = 'N'
            Fee              = '175.00'
            CurrencyCode     = 'EUR'
            Notes            = 'Delete demonstration' ) )
      MAPPED DATA(mapped_create)
      FAILED DATA(failed_create)
      REPORTED DATA(reported_create).

    out->write( 'CREATE - MAPPED' ).
    out->write( mapped_create ).
    out->write( 'CREATE - FAILED' ).
    out->write( failed_create ).
    out->write( 'CREATE - REPORTED' ).
    out->write( reported_create ).

    IF failed_create IS NOT INITIAL
       OR NOT line_exists( mapped_create-reservation[ %cid = 'RES_A' ] )
       OR NOT line_exists( mapped_create-reservation[ %cid = 'RES_B' ] ).
      ROLLBACK ENTITIES.
      out->write( 'Create failed. Demo stopped.' ).
      RETURN.
    ENDIF.

    DATA(mapped_a) = mapped_create-reservation[ %cid = 'RES_A' ].
    DATA(mapped_b) = mapped_create-reservation[ %cid = 'RES_B' ].

    DATA(uuid_a) = mapped_a-Uuid.
    DATA(uuid_b) = mapped_b-Uuid.

    " ------------------------------------------------------------
    " 2. READ Reservation A before COMMIT
    " ------------------------------------------------------------
    READ ENTITIES OF ZR_Reservation_###
      ENTITY Reservation
        FIELDS (
          Uuid
          ReservationNo
          CustomerName
          Status
          Fee
          CurrencyCode
          Notes )
        WITH VALUE #( ( Uuid = uuid_a ) )
      RESULT DATA(buffer_read)
      FAILED DATA(failed_buffer_read).

    out->write( 'Before create COMMIT - buffer read' ).
    out->write( buffer_read ).
    out->write( failed_buffer_read ).

    IF failed_buffer_read IS NOT INITIAL OR buffer_read IS INITIAL.
      ROLLBACK ENTITIES.
      out->write( 'Pre-commit read failed. Demo stopped.' ).
      RETURN.
    ENDIF.

    " ------------------------------------------------------------
    " 3. COMMIT CREATE
    " ------------------------------------------------------------
    COMMIT ENTITIES
      RESPONSE OF ZR_Reservation_###
        FAILED DATA(failed_commit_create)
        REPORTED DATA(reported_commit_create).
    DATA(create_commit_subrc) = sy-subrc.

    out->write( failed_commit_create ).
    out->write( reported_commit_create ).

    IF create_commit_subrc <> 0 OR failed_commit_create IS NOT INITIAL.
      ROLLBACK ENTITIES.
      out->write( 'Create commit failed. Demo stopped.' ).
      RETURN.
    ENDIF.

    " ------------------------------------------------------------
    " 4. READ persisted Reservation A
    " ------------------------------------------------------------
    READ ENTITIES OF ZR_Reservation_###
      ENTITY Reservation
        ALL FIELDS
        WITH VALUE #( ( Uuid = uuid_a ) )
      RESULT DATA(after_create_commit)
      FAILED DATA(failed_after_create_commit).

    out->write( 'After create COMMIT' ).
    out->write( after_create_commit ).
    out->write( failed_after_create_commit ).

    " ------------------------------------------------------------
    " 5. UPDATE in buffer, then ROLLBACK
    " ------------------------------------------------------------
    MODIFY ENTITIES OF ZR_Reservation_###
      ENTITY Reservation
        UPDATE FIELDS ( Status Notes )
        WITH VALUE #(
          ( Uuid   = uuid_a
            Status = 'C'
            Notes  = 'Buffered change - will rollback' ) )
      FAILED DATA(failed_update_rollback)
      REPORTED DATA(reported_update_rollback).

    IF failed_update_rollback IS NOT INITIAL.
      out->write( failed_update_rollback ).
      out->write( reported_update_rollback ).
      ROLLBACK ENTITIES.
      RETURN.
    ENDIF.

    READ ENTITIES OF ZR_Reservation_###
      ENTITY Reservation
        FIELDS ( Uuid ReservationNo Status Notes )
        WITH VALUE #( ( Uuid = uuid_a ) )
      RESULT DATA(before_rollback)
      FAILED DATA(failed_before_rollback).

    out->write( 'Buffered UPDATE before ROLLBACK' ).
    out->write( before_rollback ).
    out->write( failed_before_rollback ).

    IF failed_before_rollback IS NOT INITIAL OR before_rollback IS INITIAL.
      ROLLBACK ENTITIES.
      out->write( 'Buffered update read failed. Demo stopped.' ).
      RETURN.
    ENDIF.

    ROLLBACK ENTITIES.

    READ ENTITIES OF ZR_Reservation_###
      ENTITY Reservation
        FIELDS ( Uuid ReservationNo Status Notes )
        WITH VALUE #( ( Uuid = uuid_a ) )
      RESULT DATA(after_rollback)
      FAILED DATA(failed_after_rollback).

    out->write( 'After ROLLBACK' ).
    out->write( after_rollback ).
    out->write( failed_after_rollback ).

    " ------------------------------------------------------------
    " 6. UPDATE again and COMMIT
    " ------------------------------------------------------------
    MODIFY ENTITIES OF ZR_Reservation_###
      ENTITY Reservation
        UPDATE FIELDS ( Status Notes )
        WITH VALUE #(
          ( Uuid   = uuid_a
            Status = 'C'
            Notes  = 'Confirmed through EML' ) )
      FAILED DATA(failed_update_commit)
      REPORTED DATA(reported_update_commit).

    IF failed_update_commit IS NOT INITIAL.
      out->write( failed_update_commit ).
      out->write( reported_update_commit ).
      ROLLBACK ENTITIES.
      RETURN.
    ENDIF.

    COMMIT ENTITIES
      RESPONSE OF ZR_Reservation_###
        FAILED DATA(failed_commit_update)
        REPORTED DATA(reported_commit_update).
    DATA(update_commit_subrc) = sy-subrc.

    out->write( failed_commit_update ).
    out->write( reported_commit_update ).

    IF update_commit_subrc <> 0 OR failed_commit_update IS NOT INITIAL.
      ROLLBACK ENTITIES.
      out->write( 'Update commit failed. Demo stopped.' ).
      RETURN.
    ENDIF.

    " ------------------------------------------------------------
    " 7. DELETE Reservation B and COMMIT
    " ------------------------------------------------------------
    MODIFY ENTITIES OF ZR_Reservation_###
      ENTITY Reservation
        DELETE FROM VALUE #( ( Uuid = uuid_b ) )
      FAILED DATA(failed_delete)
      REPORTED DATA(reported_delete).

    out->write( failed_delete ).
    out->write( reported_delete ).

    IF failed_delete IS NOT INITIAL.
      ROLLBACK ENTITIES.
      out->write( 'Delete failed. Demo stopped.' ).
      RETURN.
    ENDIF.

    COMMIT ENTITIES
      RESPONSE OF ZR_Reservation_###
        FAILED DATA(failed_commit_delete)
        REPORTED DATA(reported_commit_delete).
    DATA(delete_commit_subrc) = sy-subrc.

    out->write( failed_commit_delete ).
    out->write( reported_commit_delete ).

    IF delete_commit_subrc <> 0 OR failed_commit_delete IS NOT INITIAL.
      ROLLBACK ENTITIES.
      out->write( 'Delete commit failed.' ).
      RETURN.
    ENDIF.

    " ------------------------------------------------------------
    " 8. Final reads
    " ------------------------------------------------------------
    READ ENTITIES OF ZR_Reservation_###
      ENTITY Reservation
        ALL FIELDS
        WITH VALUE #( ( Uuid = uuid_a ) )
      RESULT DATA(final_read)
      FAILED DATA(failed_final_read).

    out->write( 'Final Reservation A' ).
    out->write( final_read ).
    out->write( failed_final_read ).

    READ ENTITIES OF ZR_Reservation_###
      ENTITY Reservation
        FIELDS ( Uuid ReservationNo Status )
        WITH VALUE #( ( Uuid = uuid_b ) )
      RESULT DATA(deleted_read)
      FAILED DATA(failed_deleted_read).

    out->write( 'Reservation B after DELETE' ).
    out->write( deleted_read ).
    out->write( failed_deleted_read ).

    out->write( 'Now open ZR_RESERVATION_### with F8.' ).

  ENDMETHOD.

ENDCLASS.

Replace every ###.


27. Expected final persistent state ​

After a successful run:

text
92000001
→ exists
→ Status C
→ Notes = Confirmed through EML

92000002
→ deleted

This makes Data Preview useful after the demonstration.


28. Expected CREATE responses ​

MAPPED ​

Expected:

text
2 mapped Reservation entries
2 generated UUIDs
%cid values RES_A and RES_B

FAILED ​

Expected:

text
empty

REPORTED ​

Expected:

text
normally empty

29. Expected rollback observation ​

Before rollback:

text
Status = C
Notes  = Buffered change - will rollback

After rollback:

text
Status = N
Notes  = Created with EML

This is the strongest proof of the buffer in this lesson.


30. Why not use Data Preview between buffered operations? ​

The ABAP class executes one method call continuously.

The most reliable way to inspect uncommitted RAP state is therefore:

text
READ ENTITIES inside the same transaction

Use F8 after the class finishes to inspect committed persistence.


31. Data Preview verification ​

Open:

text
ZR_RESERVATION_###

Press:

text
F8

Verify:

text
ReservationNo = 92000001
Status        = C

Verify that:

text
92000002

is absent.


32. Table Data Preview verification ​

You may also inspect:

text
ZRESV_###

with:

text
Alt+F8

This is useful for comparing:

text
business-facing CDS names

with:

text
physical persistence fields

Do not use table editing to modify RAP-owned data.


33. Why the final row is intentionally left behind ​

Lesson 12 should have a visible result.

The surviving row lets students inspect:

text
managed UUID
business data
status change
administrative timestamps

after the class has finished.

The next run's EML preflight cleanup removes the old demonstration row safely.


34. Common mistake — supplying the UUID ​

Wrong idea:

text
I need to generate a UUID before EML CREATE.

Not in this BO.

Lesson 11 configured managed numbering.

Use:

text
%cid

and inspect:

text
MAPPED

for the generated key.


35. Common mistake — confusing %cid with UUID ​

%cid is not persistence identity.

It is temporary request correlation.

The UUID is the technical BO key.


36. Common mistake — forgetting COMMIT ​

If a consumer modifies the BO and then expects permanent persistence without ending the RAP transaction appropriately, the mental model is incomplete.

Teach explicitly:

text
MODIFY
≠
finished transaction

37. Common mistake — direct SQL cleanup ​

Avoid:

abap
DELETE FROM zresv_###
  WHERE reservation_no = '92000001'.

Once the BO owns this persistence, modifications should go through RAP.

Use the EML reset pattern instead.


38. Common mistake — IN LOCAL MODE ​

Do not copy:

abap
IN LOCAL MODE

from Behavior Pool tutorials into this consumer class.

The external consumer should respect the BO contract.


39. Common mistake — assuming REPORTED always contains an error ​

REPORTED is not synonymous with:

text
failure

It is a channel for RAP-reported information/messages.

A request can have reported information without every instance failing.

Lesson 13 will explore this properly.


40. Common mistake — treating FAILED as an exception object ​

FAILED is a RAP response structure.

It is not a normal ABAP exception reference.

Inspect its BO/entity components.


41. Why Lesson 12 comes before validations ​

Students now understand:

text
request
buffer
responses
commit
rollback

That gives Lesson 13 a clear question:

Where do business rules intervene in this transaction?

Without Lesson 12, validations can look like isolated syntax rather than transactional behavior.


42. Instructor discussion — direct SQL vs EML ​

Ask students to compare:

abap
UPDATE zresv_###
  SET status = 'C'
  WHERE uuid = @uuid.

with:

abap
MODIFY ENTITIES OF ZR_Reservation_###
  ENTITY Reservation
    UPDATE FIELDS ( Status )
    WITH VALUE #( ( Uuid = uuid Status = 'C' ) ).

The important difference is not syntax length.

It is architectural responsibility:

text
SQL
→ persistence operation

EML
→ Business Object operation

43. Instructor discussion — why the buffer matters ​

Ask:

If five BO changes belong to one business transaction, should each one commit independently?

No.

The transactional buffer lets RAP coordinate a consistent logical transaction and later save sequence.


44. Instructor discussion — why COMMIT ENTITIES RESPONSE OF matters ​

Future validations can run during save processing.

A MODIFY request may therefore appear acceptable during the interaction phase but saving can still report a business-rule failure later.

This is why save-phase responses deserve separate attention.


45. Certification relevance ​

Practical RAP work requires familiarity with:

text
READ ENTITIES
MODIFY ENTITIES
%cid
MAPPED
FAILED
REPORTED
COMMIT ENTITIES
ROLLBACK ENTITIES
transactional buffer

The important skill is not memorizing isolated keywords.

It is being able to read, run, diagnose, and repair an EML transaction in ADT.


46. Reference answers ​

What is EML? ​

ABAP language syntax for consuming/working with RAP Business Objects.

Why not direct SQL writes? ​

Because direct writes bypass the BO transactional/business contract.

What is %cid? ​

A preliminary create request identifier supplied by the consumer.

What is MAPPED? ​

A response that maps preliminary identifiers to generated/final identity information where relevant.

What is FAILED? ​

A structured response identifying failed RAP entity operations.

What is REPORTED? ​

A structured channel for RAP-reported information and messages.

What is the transactional buffer? ​

The working BO state for the current RAP transaction before the final save/rollback boundary.

What does COMMIT do? ​

Triggers the RAP save sequence for the current transaction. On success, the buffered changes are persisted together; a validation failure prevents that transaction from being committed.

What does ROLLBACK do? ​

Discards current RAP transactional changes and resets the buffer.


47. End-of-lesson instructor audit ​

Before Lesson 13, students should be able to explain this without notes:

text
CREATE
  ↓
MAPPED / FAILED / REPORTED
  ↓
buffer
  ↓
READ own changes
  ↓
COMMIT or ROLLBACK
  ↓
persisted state

If that is clear, the course is ready to add business rules.