The Story Behind Created/Changed Fields in RAP

The Story Behind Created/Changed Fields in RAP

SAP RAP

In the previous two blogs, we built a Billing Document app using RAP Managed scenario and then extended it with a child entity for items.
If you looked closely at our database tables and CDS views, you might have noticed a set of fields:

  • CreatedBy (Data element: syuname)

  • CreatedAt (Data element: timestamp)

  • LastChangedBy (Data element: syuname)

  • LastChangedAt (Data element: timestamp)

  • LocalLastChangedAt (Data element: timestamp)

You may be wondering, why are these fields there? Do we need to write code to update them?
Let’s go step-by-step.


Why these fields exist

These fields are part of what RAP calls administrative data.
They help store:

  • Who created or last changed the record

  • When the record was created or last changed

  • When the record (or its composition tree) was last changed, used for concurrency control


When each field gets updated in RAP Managed scenario

Field When it gets updated
CreatedBy When a new record is created in the active table (or when a draft is activated for the first time). Filled with the current user ID.
CreatedAt Same moment as CreatedBy. Filled with the current UTC timestamp.
LastChangedBy Every time the record in the active table is changed (including draft activation). Filled with the current user ID.
LastChangedAt Same moment as LastChangedBy. Filled with the current UTC timestamp.
LocalLastChangedAt Updated every time this record or any of its dependent child records change. Used by RAP for optimistic locking (ETag checks).

Do we need to write any code?

In a managed RAP scenario - no.
As long as:

  1. These fields are present in your table

  2. They are exposed in your CDS view

  3. They are mapped in your Behavior Definition (BDEF)

RAP will update them automatically during create and update operations.

Example from our Billing Document BDEF mapping:

mapping for zbillingdoc
{
  CreatedBy          = createdby,
  CreatedAt          = createdat,
  LastChangedBy      = lastchangedby,
  LastChangedAt      = lastchangedat,
  LocalLastChangedAt = locallastchangedat
}

No determination or save logic is needed, the framework takes care of it.


A quick example

  1. Create a Billing DocumentCreatedBy and CreatedAt are filled, LastChangedBy and LastChangedAt are also set to the same values, LocalLastChangedAt is set.

  2. Change the Billing Document → Only LastChangedBy, LastChangedAt, and LocalLastChangedAt are updated.


Key takeaways

  • These are administrative fields maintained by RAP

  • Correct BDEF mapping is essential for them to work automatically

  • In managed scenario, no extra code is needed

  • LocalLastChangedAt is especially important for concurrency control in RAP


In our Billing Document app, adding these fields means we always know who created or changed a record and when, without writing a single line of extra logic.