Behavior implementation pattern
What you'll learn
Implement RAP behavior in a behavior pool with one lhc_<entity> handler per entity, reading and writing only via READ/MODIFY ENTITIES in local mode under strict(2).
- The behavior pool is one global class; one local lhc_<entity> handler per entity inherits from cl_abap_behavior_handler.
- Validations map to methods `for validate on save`; determinations to `for determine on save`.
- Access data only via READ ENTITIES / MODIFY ENTITIES ... IN LOCAL MODE — never direct SQL.
The behavior definition declares what happens; the behavior pool implements it. The pool is a single global class (named in the BDEF's `implementation in class`), and inside it you define one local handler class — `lhc_<entity>` — per entity, each inheriting from `cl_abap_behavior_handler`. The validations and determinations declared in the BDEF map to handler methods marked `for validate on save` and `for determine on save`.
Inside a handler you never touch the database directly. You read and write through the BO runtime with `read entities of ... in local mode` and `modify entities of ... in local mode`. 'In local mode' means the call runs inside the current BO transaction and skips the DCL authorization check — appropriate because you are already inside the trusted BO boundary, but it means you must never hand that result to a UI without re-checking authorization. Failures are reported back through the framework tables `failed-<entity>` and `reported-<entity>`, not by raising exceptions.
Use `strict ( 2 )` in all new RAP code. Strict mode 2 enables the latest syntax checks and forbids deprecated patterns (for example an eager `read` without an explicit `result`), so the compiler catches contract mistakes early. The pattern for a determination is: read the keys you were handed, compute, then `modify entities ... update fields ( ... )` naming exactly the fields you set — a field omitted from that list is silently not updated.
Key points
- The behavior pool is one global class; one local lhc_<entity> handler per entity inherits from cl_abap_behavior_handler.
- Validations map to methods `for validate on save`; determinations to `for determine on save`.
- Access data only via READ ENTITIES / MODIFY ENTITIES ... IN LOCAL MODE — never direct SQL.
- IN LOCAL MODE runs inside the BO transaction and skips DCL — re-check auth before exposing results.
- Report problems through failed-<entity> / reported-<entity>, and always use strict ( 2 ).
Examples
Read the keys in local mode, loop, and append to failed/reported instead of raising — the RAP way to reject a save.
ABAPmethod validatecustomer.
read entities of zi_orderheader in local mode
entity orderheader
fields ( customerid )
with corresponding #( keys )
result data(orders).
loop at orders assigning field-symbol(<order>).
if <order>-customerid is initial.
append value #( %tky = <order>-%tky ) to failed-orderheader.
append value #( %tky = <order>-%tky
%msg = new_message_with_text(
severity = if_abap_behv_message=>severity-error
text = 'CustomerId required' ) )
to reported-orderheader.
endif.
endloop.
endmethod.Source notes: clean-core-curriculum §4.2
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.