RAP Basics
Architect / Cross-trackintermediate

RAP Basics Part 5: Root Entity, Child Entity and Composition

Key takeaway

Model multi-level RAP business objects: root and child entities, composition versus association, the to-parent association, lock master and lock dependent, authorization master and dependent, create-by-association, and how the composition tree defines the BO boundary.

Explanation

📌 KEY POINTS
✅ A RAP BO is a composition tree: one root entity and child (and grandchild) entities that live and die with the root.

✅ Composition = existential dependency (bookings exist only within a travel); association = loose reference (travel → agency).

✅ The root is lock master and authorization master; children are lock dependent / authorization dependent via the to-parent association.

✅ Children are created through the parent: create by association (_Booking { create; }).

⚠️ Putting two independent objects in one composition tree makes them lock together — users block each other unnecessarily.

━━━━━━━━━━━━━━━━━━━━
▶ WHERE WE ARE

Part 4 fixed the implementation type. Now we extend the BO from one entity to a tree.

━━━━━━━━━━━━━━━━━━━━
▶ 1. COMPOSITION VS ASSOCIATION

  • composition [0..*] of ZI_Booking as _Booking — child belongs to the root.
  • association [0..1] to ZI_Agency as _Agency — just a reference to another object.
  • Deleting the root deletes all composition children (cascading in managed).

━━━━━━━━━━━━━━━━━━━━
▶ 2. THE CHILD VIEW

  • define view entity ZI_Booking … association to parent ZI_Travel as _Travel on $projection.TravelUUID = _Travel.TravelUUID.
  • Child key usually its own UUID plus parent UUID as a normal field.

━━━━━━━━━━━━━━━━━━━━
▶ 3. BDEF FOR THE TREE

  • Root: lock master, authorization master ( instance ), etag master.
  • Child: lock dependent by _Travel, authorization dependent by _Travel, etag master (its own field).
  • Root declares association _Booking { create; } — create by association.
  • Child declares association _Travel; to allow navigation back.

━━━━━━━━━━━━━━━━━━━━
▶ 4. BO BOUNDARY DESIGN

  • Question: must these objects be changed together in one transaction?
  • Yes → composition. No → separate BOs linked by association.
  • Deep trees (4+ levels) make locks coarse and payloads heavy — keep trees shallow.

━━━━━━━━━━━━━━━━━━━━
▶ 5. DEEP OPERATIONS

  • Fiori Elements object page shows children as a table facet.
  • EML: CREATE BY \_Booking creates children for an existing parent (Part 10).
  • OData V4 deep create posts parent and children in one request.

━━━━━━━━━━━━━━━━━━━━
▶ STEP BY STEP

  1. Create table ZBOOKING_A with booking_uuid, parent_uuid, fields, admin fields.
  2. Add composition to ZI_Travel; create ZI_Booking with association to parent.
  3. Extend the BDEF with the child entity (lock/authorization dependent).
  4. Add create by association on the root.
  5. Redirect compositions in projections (Part 3).

✅ CHECKPOINT: you can explain why the child is lock dependent and what happens to bookings when a travel is locked.

Code example

ABAP Code
// ===== STEP 1: root with composition =====define root view entity ZI_Travel  as select from ztravel_a  composition [0..*] of ZI_Booking as _Booking  association [0..1] to /DMO/I_Agency as _Agency on $projection.AgencyID = _Agency.AgencyID{  key travel_uuid as TravelUUID,      travel_id   as TravelID,      agency_id   as AgencyID,      @Semantics.systemDateTime.localInstanceLastChangedAt: true      local_last_changed_at as LocalLastChangedAt,      _Booking,      _Agency} // ===== STEP 2: child with association to parent =====define view entity ZI_Booking  as select from zbooking_a  association to parent ZI_Travel as _Travel    on $projection.TravelUUID = _Travel.TravelUUID{  key booking_uuid  as BookingUUID,      parent_uuid   as TravelUUID,      booking_id    as BookingID,      flight_date   as FlightDate,      @Semantics.systemDateTime.localInstanceLastChangedAt: true      local_last_changed_at as LocalLastChangedAt,      _Travel} // ===== STEP 3: BDEF for the composition tree =====managed implementation in class zbp_i_travel unique;strict ( 2 ); define behavior for ZI_Travel alias Travelpersistent table ztravel_alock masterauthorization master ( instance )etag master LocalLastChangedAt{  create; update; delete;  field ( readonly, numbering : managed ) TravelUUID;  association _Booking { create; }} define behavior for ZI_Booking alias Bookingpersistent table zbooking_alock dependent by _Travelauthorization dependent by _Traveletag master LocalLastChangedAt{  update; delete;  field ( readonly ) TravelUUID;  field ( readonly, numbering : managed ) BookingUUID;  association _Travel;}

Real project scenario

A distributor built a RAP BO where customer master extension data and all sales quotations for that customer were one composition tree (customer as root, quotations as children). In go-live week, sales reps editing different quotations for the same key account blocked each other, because the whole tree was locked through the root. The architect split the design: quotation became its own root BO with an association to the customer extension BO. Lock conflicts dropped to zero, and quotation payloads became much smaller.

Common mistakes

  • Modelling independent objects as composition children, making locks too coarse.
  • Using an association where the child should be deleted with the parent.
  • Forgetting "association to parent" in the child view, so the BDEF cannot declare lock dependent.
  • Declaring create on the child directly instead of create by association on the parent.
  • Very deep composition trees that make every change lock and load everything.

Best practices

  • Draw the BO boundary around "what must change together in one transaction".
  • Keep composition trees shallow (root + one or two levels).
  • Root = lock master, authorization master; children dependent via the to-parent association.
  • Give each entity its own ETag field.
  • Use associations for references to other BOs and master data.

Interview angle

Questions: "Composition vs association in RAP?", "What is lock master and lock dependent?", "How do you create a child entity in RAP?"
Strong answer: composition models existential dependency within one BO and defines the lock and transaction boundary; association references other objects. The root is lock/authorization master; children use lock/authorization dependent by the to-parent association. Children are created by association from the parent. Architect-level answers discuss BO boundary design and lock contention.

Practice this lesson

Quick check

1. Bookings exist only within a travel and must be deleted together with it. How are they modelled in the travel view?

2. How are child instances (e.g. bookings) created in a RAP business object?

3. In the BDEF of the child entity Booking, which statement makes it use the lock of the root Travel?

Interview questions

1. How would you design a RAP business object with header and items?

Answer it in your own words first, then compare.

2. In a claim application, developers made claim items a separate root BO so items could be created on their own. Now items exist without a claim header and item changes are not locked with the claim. How should the model look?

Answer it in your own words first, then compare.

Practice more with Interview AI →

Reference-verified: the steps are checked against official SAP documentation and tutorials, and object and field names in the sample code are checked for consistency. The code has not been compiled or run on an SAP system by ERPClimb. Syntax marked release-dependent varies by SAP release, so check it in your own system.

More lessons in this topic

Interview questions on this topic

Related SAP topics