Appearance
Lesson 17 Companion — RAP Draft
This companion supports:
text
Lesson 17 — RAP DraftThe core change is:
text
short-lived RAP transaction
→ persisted draft editing lifecycle1. Draft architecture
text
ZRESV_###
Active Persistence
↑
│ Activate
│
ZDRESV_###
Draft Persistence
↑
│
Draft-enabled RAP Runtime
↑
OData V4 / Fiori Elements2. Exclusive draft
Lesson 17 uses:
abap
with draft;This is exclusive draft.
One draft owner has exclusive modify access to the draft.
Collaborative Draft is a separate RAP capability and is not required here.
3. Draft persistence
Each draft-enabled entity requires:
text
active persistence
draft persistenceFor this single-node BO:
text
ZRESV_###
ZDRESV_###Use ADT Quick Fix to generate the draft table.
4. Generated draft table
SAP's draft-table generator derives storage from the CDS entity and adds technical draft administration.
Do not manually design:
text
draft admin fieldsand do not directly write to the table.
5. Total ETag
Draft BOs require:
text
total etagon the lock master.
Reference:
abap
lock master
total etag LastChangedAt6. Local ETag vs total ETag
text
LocalLastChangedAt
→ etag master
→ normal entity concurrency
LastChangedAt
→ total etag
→ draft/active concurrency across draft lifetimeKeep both.
7. Owner determination reference
BDEF:
abap
field ( readonly ) ResponsibleUser;
determination setResponsibleUser on modify { create; }Implementation:
abap
METHOD setResponsibleUser.
READ ENTITIES OF ZR_Reservation_### IN LOCAL MODE
ENTITY Reservation
FIELDS ( ResponsibleUser )
WITH CORRESPONDING #( keys )
RESULT DATA(reservations).
DATA updates TYPE TABLE FOR UPDATE ZR_Reservation_###.
DATA current_user TYPE abp_creation_user.
current_user = cl_abap_context_info=>get_user_technical_name( ).
LOOP AT reservations INTO DATA(reservation)
WHERE ResponsibleUser IS INITIAL.
APPEND VALUE #(
%tky = reservation-%tky
ResponsibleUser = current_user
) TO updates.
ENDLOOP.
IF updates IS NOT INITIAL.
MODIFY ENTITIES OF ZR_Reservation_### IN LOCAL MODE
ENTITY Reservation
UPDATE FIELDS ( ResponsibleUser )
WITH updates.
ENDIF.
ENDMETHOD.8. Why automatic owner matters
The Lesson 15 DCL is:
text
ResponsibleUser = aspect userNew drafts should acquire ownership automatically.
Otherwise UI create could depend on users knowing and typing technical identities.
9. Base BDEF reference
abap
managed implementation in class zbp_r_resv_### unique;
strict ( 2 );
with draft;
define behavior for ZR_Reservation_### alias Reservation
persistent table zresv_###
draft table zdresv_###
lock master
total etag LastChangedAt
authorization master ( global, instance )
etag master LocalLastChangedAt
{
create;
update;
delete;
field ( numbering : managed, readonly ) Uuid;
field ( readonly )
Status,
ResponsibleUser,
LocalCreatedBy,
LocalCreatedAt,
LocalLastChangedBy,
LocalLastChangedAt,
LastChangedAt;
field ( mandatory:create, readonly:update ) ReservationNo;
field ( features : instance ) Fee, CurrencyCode;
determination setInitialStatus on modify { create; }
determination setResponsibleUser on modify { create; }
validation validateCustomer on save
{ create; field CustomerName; }
validation validateDate on save
{ create; field ReservationDate; }
validation validateFee on save
{ create; field Fee, CurrencyCode; }
action ( features : instance, authorization: update )
confirm result [1] $self;
action ( features : instance, authorization: update )
cancel result [1] $self;
draft action Edit;
draft action Activate optimized;
draft action Discard;
draft action Resume;
draft determine action Prepare
{
validation validateCustomer;
validation validateDate;
validation validateFee;
}
mapping for zresv_###
{
Uuid = uuid;
ReservationNo = reservation_no;
CustomerName = customer_name;
CustomerEmail = customer_email;
WorkshopCode = workshop_code;
ReservationDate = reservation_date;
Status = status;
ResponsibleUser = responsible_user;
Fee = fee;
CurrencyCode = currency_code;
Notes = notes;
LocalCreatedBy = local_created_by;
LocalCreatedAt = local_created_at;
LocalLastChangedBy = local_last_changed_by;
LocalLastChangedAt = local_last_changed_at;
LastChangedAt = last_changed_at;
}
}10. Draft actions
Edit
text
active → edit draftActive persistence remains.
Activate
text
new draft → CREATE active
edit draft → UPDATE active
successful activation → draft removedDiscard
text
delete draft onlyResume
text
continue a durable draft after lock expirationPrepare
text
execute assigned validations/determinations before activation11. Activate optimized
Use:
abap
draft action Activate optimized;The optimized variant can skip unnecessary repeated Prepare work when RAP knows the required validations/determinations have already executed and remain valid.
12. Prepare reference
abap
draft determine action Prepare
{
validation validateCustomer;
validation validateDate;
validation validateFee;
}Only already-defined BO validations/determinations can be assigned.
13. Prepare and Fiori Save
For a draft instance, Fiori Elements Save invokes Prepare before Activate.
Conceptual flow:
text
Save
↓
Prepare
↓
validations
↓
ActivateIf validation fails:
text
Activate does not complete
draft remains14. Draft authorization impact
Draft enablement adds framework actions.
Existing authorization implementations must handle requests for:
text
EditApply the Lesson 15 update-style policy to Edit.
Prepare is a draft determine action, not an independently authorization-controlled action. Its components do not exist in the generated authorization structures, so do not check or populate authorization fields for it.
15. Global authorization pattern
Training model:
text
create = allowed
delete = allowed
update-style requests = allowedUpdate-style requests now include:
text
%update
%action-EditReference:
abap
IF requested_authorizations-%update = if_abap_behv=>mk-on.
result-%update = if_abap_behv=>auth-allowed.
ENDIF.
IF requested_authorizations-%action-Edit = if_abap_behv=>mk-on.
result-%action-Edit = if_abap_behv=>auth-allowed.
ENDIF.The global authorization result is a structure. Fill only requested components and retain the existing %create and %delete handling.
16. Instance authorization pattern
Treat:
text
%update
%action-Editwith the same owner check:
text
ResponsibleUser = current userThe instance authorization result is a table. Append one row per instance with its full %tky, then fill the requested components on that row. Retain Lesson 15's classroom cleanup policy for %delete.
Reference:
abap
METHOD get_instance_authorizations.
READ ENTITIES OF ZR_Reservation_### IN LOCAL MODE
ENTITY Reservation
FIELDS ( ResponsibleUser )
WITH CORRESPONDING #( keys )
RESULT DATA(reservations)
FAILED failed.
DATA current_user TYPE abp_creation_user.
current_user = cl_abap_context_info=>get_user_technical_name( ).
LOOP AT reservations INTO DATA(reservation).
APPEND VALUE #(
%tky = reservation-%tky
) TO result ASSIGNING FIELD-SYMBOL(<authorization>).
IF requested_authorizations-%update = if_abap_behv=>mk-on.
<authorization>-%update =
COND #(
WHEN reservation-ResponsibleUser = current_user
THEN if_abap_behv=>auth-allowed
ELSE if_abap_behv=>auth-unauthorized
).
ENDIF.
IF requested_authorizations-%action-Edit = if_abap_behv=>mk-on.
<authorization>-%action-Edit =
COND #(
WHEN reservation-ResponsibleUser = current_user
THEN if_abap_behv=>auth-allowed
ELSE if_abap_behv=>auth-unauthorized
).
ENDIF.
IF requested_authorizations-%delete = if_abap_behv=>mk-on.
<authorization>-%delete = if_abap_behv=>auth-allowed.
ENDIF.
ENDLOOP.
ENDMETHOD.Copying the full %tky preserves each instance's active/draft identity. Direct assignments such as result-%update belong to global authorization; in the instance handler, assign to the appended row.
Do not confuse:
text
draft Editwith:
text
business confirm/cancel17. Activate authorization
Activate itself is not modeled as an unrelated business privilege in this lesson.
The active create/update performed by activation is still subject to the BO's modifying authorization.
18. Discard authorization
Discard manages the user's draft persistence.
It is not the same as:
text
delete active ReservationDo not reuse active delete business semantics blindly.
19. Projection BDEF reference
abap
projection;
strict ( 2 );
use draft;
define behavior for ZC_Reservation_### alias Reservation
use etag
{
use create;
use update;
use delete;
use action Edit;
use action Activate;
use action Discard;
use action Resume;
use action Prepare;
use action confirm;
use action cancel;
}20. Why projection needs use draft
A base BO can be draft-enabled while a particular projection is not.
Draft exposure is a projection choice.
The Lesson 16 UI projection should be draft-enabled.
21. Why projection does not repeat draft table
The draft table is an implementation detail of the base behavior.
Projection reuses it automatically.
Do not write:
text
draft table ...
total etag ...in the projection BDEF.
22. Existing service artifacts
No new:
text
Service Definition
Service Bindingis required.
The existing:
text
OData V4 UIservice can expose the newly draft-enabled projection.
23. New draft lifecycle
Fiori Create:
text
CREATE request with draft state
↓
new draft table row
↓
determinations on modify
↓
user edits
↓
Save
↓
Prepare
↓
Activate
↓
active row created
↓
draft row removed24. Edit draft lifecycle
text
active row
↓ Edit
copy to draft table
↓
user edits draft
├─ Discard → draft removed, active unchanged
└─ Save → Prepare → Activate → active updated25. Draft table inspection
During training, Table Data Preview is useful for proving:
text
draft persistence really existsBut do not make business logic depend on draft-table SQL.
The draft table is a runtime artifact.
26. Active table inspection
While an edit draft exists:
text
active table
→ old saved values
draft table
→ work-in-progress valuesThis is the clearest demonstration of draft isolation.
27. Invalid draft
A draft may temporarily contain business-invalid values.
That is acceptable while the user is editing.
Activation must still enforce business validity.
This is why Prepare + validation is central.
28. Invalid active data is still forbidden
Draft does not weaken:
text
validateCustomer
validateDate
validateFeeIt changes when/how the UI gets a chance to correct invalid work-in-progress data.
29. Draft locks
Exclusive draft establishes durable draft ownership/locking behavior beyond the short database transaction.
The lock is associated with the draft lifecycle rather than one ABAP request.
30. Resume
Resume matters after the original exclusive lock has expired while the draft still exists.
It recreates the edit lock if the runtime permits the user to continue.
No classroom timeout simulation is required.
31. Total ETag invalidation
If active data changes after an edit draft is created:
text
draft based on old active versionThe total ETag lets RAP recognize the stale relationship.
32. Business status remains independent
Examples:
text
active + Status N
draft + Status N
active + Status C
draft based on Status CNever encode draft lifecycle in the business Status domain.
33. Managed draft runtime
Even for unmanaged RAP BOs, draft handling itself is framework-managed.
For our current managed BO:
text
managed persistence
+
managed draft runtimefit naturally.
This course uses managed RAP for the hands-on application.
34. Quick Fix is preferred
For draft table creation:
text
cursor on draft table name
Ctrl+1
Create draft tableThis is safer and more certification-relevant than memorizing generated technical columns.
35. If root CDS changes later
If view elements change, ADT can offer a Quick Fix to adjust the draft table.
Draft persistence must stay compatible with the entity shape.
36. Fiori Create vs direct EML
Fiori draft Create creates a draft.
EML can explicitly distinguish draft and active operations.
Lesson 17 focuses on the Fiori/OData V4 lifecycle because that is where persistent draft editing becomes most visible.
37. Fiori Edit
Edit:
text
copies active data to draftThe active version remains the published business version until activation.
38. Fiori Save
Save:
text
Prepare
+
Activateconceptually.
The exact requests are handled by the RAP/Fiori integration.
39. Fiori Cancel
The UI operation may be shown as:
text
Cancel
Discarddepending on context/version.
Conceptually it executes the draft discard lifecycle and leaves active data unchanged.
40. Action availability
Existing business actions:
text
confirm
cancelstill use feature control.
Draft capability does not replace business feature control.
41. Read authorization
Projection DCL from Lesson 16 remains required.
Draft enablement does not make DCL unnecessary.
42. Write authorization
Owner-based RAP authorization remains required.
Draft enablement adds authorization runtime paths rather than replacing them.
43. Common activation error — missing draft table
Symptom:
text
with draft
draft table name declared
table does not existFix:
text
Ctrl+1 on draft table name
generate table
activate table44. Common activation error — missing total ETag
Draft BO:
text
with draftbut no:
text
total etagFix the lock-master line.
45. Common strict-mode error — missing draft action
Explicitly declare:
text
Edit
Activate
Discard
Resume
Preparein base behavior.
46. Common strict projection error
If projection has:
text
use draftalso explicitly expose all required draft actions in strict mode.
47. Common runtime error — Edit denied
Check:
text
ResponsibleUser
current user
global authorization handler
instance authorization handler
%action-Edit authorization result48. Common syntax errors — authorization components and result shape
If authorization code references a component for Prepare, remove that reference. Prepare is a draft determine action and has no independent authorization component.
Handle %action-Edit with the update-style policy, and retain normal %update and %delete handling.
If instance authorization code treats result as a structure, append a table row with %tky and fill the requested components on that row instead. See section 16.
49. Common runtime error — new draft hidden
Check:
text
setResponsibleUser determination
projection DCL
current user
draft create authorizationNew draft ownership should be assigned automatically.
50. Common runtime error — invalid data activates
Check:
text
validation exists?
validation still on save?
validation listed in Prepare?
projection uses draft?51. Common misunderstanding — draft row after Save
A successfully activated draft is normally removed.
The active table contains the new saved version.
Do not expect both to remain indefinitely.
52. Common misunderstanding — Discard is active delete
Discard removes draft persistence.
It does not mean:
text
delete active business object53. Certification object map
text
Base BDEF
→ with draft
→ draft table
→ total etag
→ draft actions
→ Prepare
Draft table
→ persistent work-in-progress storage
Behavior Pool
→ existing rules + draft-aware auth changes
Projection BDEF
→ use draft + use draft actions
OData V4 UI
→ draft-aware consumer54. Instructor demo sequence
Recommended:
text
1. Show non-draft service
2. Add owner determination
3. Add with draft
4. declare draft table
5. Quick Fix generate table
6. add total ETag
7. add draft actions
8. add validations to Prepare
9. adapt authorization
10. add use draft to projection
11. activate
12. Preview → Create
13. inspect draft table before Save
14. Save → inspect active/draft tables
15. Edit → change Notes
16. compare active vs draft
17. Discard
18. Edit → invalid date
19. Save → validation message
20. correct → Save55. Ready-for-Lesson-18 test
Students are ready when they can explain:
text
active vs draft
new draft vs edit draft
draft table
total ETag
Edit
Activate
Discard
Resume
Prepare
validation before activation
draft-aware authorization
use draft in projectionwithout confusing any of those concepts with business Status.