10.3Bloom · AnNot started

RAP pitfalls

Reading depth

What you'll learn

An ETag pinned to a field that never changes silently switches off optimistic locking — anchor it to a LocalLastChangedAt that a determination bumps.

  • An ETag on a non-changing field silently disables optimistic locking — use a LocalLastChangedAt updated by a determination.
  • READ/MODIFY ENTITIES IN LOCAL MODE skips DCL — fine inside the BO, a leak if surfaced without re-checking auth.
  • UPDATE FIELDS ( ... ) is an allow-list — a field you forget to list is silently not updated, no error.

The RAP pitfall that quietly corrupts data integrity is a mis-wired ETag. Optimistic locking compares the ETag the client read against the current value on save; if they differ, the save is rejected. But if you bind the ETag to a field that never changes, the comparison always passes and concurrent edits silently overwrite each other — locking is effectively disabled with no error anywhere. The correct pattern is an ETag master on a LocalLastChangedAt field that a determination updates on every save, so the token genuinely moves.

Two more traps come from the LOCAL MODE keyword. READ/MODIFY ENTITIES ... IN LOCAL MODE deliberately skips DCL authorization — which is correct *inside* the behaviour pool where you have already passed the entry-point check, but a defect if you hand that result to a UI or external consumer without re-checking. And MODIFY ENTITIES ... UPDATE FIELDS ( ... ) updates *only* the fields you list: forget one in the parenthesised list and that field is silently left unchanged, with no error. The FIELDS list is an allow-list, not a hint.

The last is ordering with late numbering. ADJUST_NUMBERS assigns the real key once per save, *after* the determination phase. So a DETERMINE ON SAVE that runs before numbering cannot read the final key — it sees the temporary one. If downstream logic depends on the assigned number, it must run in or after the numbering step, not before it.

Key points

  • An ETag on a non-changing field silently disables optimistic locking — use a LocalLastChangedAt updated by a determination.
  • READ/MODIFY ENTITIES IN LOCAL MODE skips DCL — fine inside the BO, a leak if surfaced without re-checking auth.
  • UPDATE FIELDS ( ... ) is an allow-list — a field you forget to list is silently not updated, no error.
  • Late numbering (ADJUST_NUMBERS) runs after determinations — you cannot read the assigned key before it.

Examples

BeforeDead ETag

OrderId never changes, so the ETag comparison always matches — concurrent saves silently clobber each other.

ABAPmanaged implementation in class zbp_i_order unique;
define behavior for zi_order alias order
persistent table zorder_hdr
etag master order_id { }
AfterLive ETag on a moving timestamp

A determination updates local_last_changed_at on every save, so the ETag actually moves and stale writes are rejected.

ABAPmanaged implementation in class zbp_i_order unique;
define behavior for zi_order alias order
persistent table zorder_hdr
etag master local_last_changed_at { }

Source notes: clean-core-curriculum §10.3

Ask Claude

Build a prompt from this lesson + your question and open a fresh Claude chat with it pre-filled — handy for adapting a before/after pattern to your own object.