Skip to content

Lesson 6 Companion — CDS Semantics & Annotations ​

This companion expands Lesson 6 — CDS Semantics & Annotations.

It includes:

  • current amount/currency and quantity/unit patterns;
  • text-element vs text-association distinctions;
  • annotation scope;
  • annotation propagation rules;
  • @Metadata.ignorePropagatedAnnotations;
  • ADT Active Annotations guidance;
  • complete guided reference code;
  • complete practice reference code;
  • troubleshooting;
  • current SAP references.

How to use this companion

Use it when checking an annotation's purpose, debugging inherited metadata, or comparing your semantic model with a complete reference implementation.

Related lesson files: guided lesson · practice assignment


1. Why this lesson comes after associations ​

Semantic metadata is most useful once the CDS model already contains meaningful elements and relationships.

Before Lesson 6, you know:

text
data sources
calculations
joins
associations
path fields
navigation

Now distinguish:

text
how data is obtained

from:

text
what the data means

For example:

text
_Carrier.Name

obtains the carrier description.

text
@ObjectModel.text.element

describes the relationship between an identifier and that description.


2. Current SAP amount/currency pattern ​

Current SAP RAP and Flight Reference examples use:

abap
@Semantics.amount.currencyCode: 'CurrencyCode'
Flight.price as Price,

Flight.currency_code as CurrencyCode

The annotation is on the amount field.

Its value is the name of the CDS currency element.

This is a reference relationship:

text
Price → CurrencyCode

not a hard-coded currency.


3. Current View Entity currency-code nuance ​

SAP's current RAP documentation explicitly notes that, for CDS View Entities, the currency key field does not need to be separately annotated with:

abap
@Semantics.currencyCode: true

when it is already defined as the currency field in the underlying database table.

This differs from many older CDS tutorials.

The course therefore follows current View Entity examples.

The amount reference remains explicit:

abap
@Semantics.amount.currencyCode: 'CurrencyCode'

4. Current quantity/unit pattern ​

SAP's current /DMO/I_Connection example uses:

abap
@Semantics.quantity.unitOfMeasure: 'DistanceUnit'
Connection.distance as Distance,

Connection.distance_unit as DistanceUnit

The model says:

text
Distance → DistanceUnit

The unit is not hard-coded in the annotation.


5. Amounts and quantities are semantic pairs ​

A value without its reference field can be ambiguous.

text
100

is not enough for an amount.

Likewise:

text
250

is not enough for a physical quantity.

The semantic pairs are:

text
amount + currency
quantity + unit

The reference fields belong to the model contract.


6. Why aliases matter for semantic references ​

Annotations refer to CDS element names.

If a higher layer changes:

text
CurrencyCode

to:

text
TransactionCurrency

then the higher layer's amount annotation should reference:

text
'TransactionCurrency'

not the source's old alias.

Current SAP projection-view documentation explicitly demonstrates this need.


7. Annotation scope ​

Current ABAP CDS documentation distinguishes scopes such as:

text
#ENTITY
#VIEW
#ELEMENT
#PARAMETER

For this course:

text
@EndUserText.label

is used as header/entity metadata.

text
@Semantics.amount.currencyCode
@Semantics.quantity.unitOfMeasure
@ObjectModel.text.element

are element-level annotations and are placed immediately before the relevant element.


8. Annotation evaluation ​

Not all CDS annotations are interpreted by the same runtime.

Some are ABAP annotations.

Some are framework-specific.

SAP documentation describes semantic currency metadata as being interpreted by the RAP/SADL layer and translated into corresponding OData metadata.

Therefore, an annotation can be important even when:

text
Data Preview rows look unchanged
ABAP SQL syntax is unchanged

9. Guided Flight Price reference ​

abap
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Flight Price'

define view entity ZI_Flight_Price_###
  as select from /dmo/flight as Flight
{
  key Flight.carrier_id      as CarrierId,
  key Flight.connection_id   as ConnectionId,
  key Flight.flight_date     as FlightDate,

      @Semantics.amount.currencyCode: 'CurrencyCode'
      Flight.price           as Price,

      Flight.currency_code   as CurrencyCode
}

This mirrors the current SAP /DMO/I_Flight pattern.


10. Guided semantic Route reference ​

abap
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Semantic Route'
@Metadata.ignorePropagatedAnnotations: true

define view entity ZI_Route_Sem_###
  as select from ZI_Route_Assoc_### as Route
{
      @ObjectModel.text.element: ['CarrierName']
  key Route.CarrierId,

  key Route.ConnectionId,

      Route.CarrierName,

      @ObjectModel.text.element: ['OriginAirportName']
      Route.OriginAirportId,

      Route.OriginAirportName,
      Route.OriginCity,
      Route.OriginCountryCode,

      @ObjectModel.text.element: ['DestinationAirportName']
      Route.DestinationAirportId,

      Route.DestinationAirportName,
      Route.DestinationCity,
      Route.DestinationCountryCode,

      Route.DepartureTime,
      Route.ArrivalTime,

      @Semantics.quantity.unitOfMeasure: 'DistanceUnit'
      Route.Distance,

      Route.DistanceUnit,

      Route._Carrier,
      Route._OriginAirport,
      Route._DestinationAirport
}

11. Why use ignorePropagatedAnnotations in the guided layer ​

The semantic layer intentionally uses:

abap
@Metadata.ignorePropagatedAnnotations: true

to make the metadata contract explicit and stable.

Current SAP documentation explains that this disables inheritance from lower layers and is included as true by default in the standard View Entity template.

This provides a concrete reason to repeat required semantics locally.


12. Propagation is not universal ​

Element annotations can propagate through direct projections/selections.

However, propagation can be stopped by:

text
@Metadata.ignorePropagatedAnnotations
local override
annotation value null
expressions/calculations
renaming/reference changes

Do not assume:

text
annotations always inherit

or:

text
annotations never inherit

Both are inaccurate.

Use ADT tools to inspect the active result.


13. Expressions and propagation ​

Current SAP documentation states that calculations and expressions interrupt normal annotation inheritance.

That includes scenarios such as:

text
CAST
arithmetic
other expressions

A calculated amount or quantity therefore needs careful semantic modeling.

If the result is still an amount or quantity, it should carry the correct reference semantics for the result, not merely rely on an operand's metadata.


14. Active Annotations ​

Current ADT supports:

text
Open With
  → Active Annotations

for an activated Data Definition.

It shows:

text
annotated element
active annotation
annotation value
origin data source
origin data element

It includes locally defined and inherited annotations.

This should become part of the CDS debugging toolkit.


15. Annotation Propagation tooling ​

ADT also provides annotation-propagation analysis tooling on supported releases.

This can show:

text
active values
inactive/overridden values
originating CDS layers
metadata extensions

The student lesson only requires Active Annotations.

The propagation view is useful for diagnosing more complex layered models.


16. Text element semantics ​

SAP uses:

abap
@Semantics.text: true

to identify an element as a human-readable text field.

Current Flight Reference examples include text-bearing fields such as:

text
/DMO/I_Carrier.Name
/DMO/I_Customer.LastName

This identifies the nature of the field itself.


17. @ObjectModel.text.element ​

This annotation establishes an identifier-to-description relationship when the text element is available in the same entity.

Example:

abap
@ObjectModel.text.element: ['CarrierName']
CarrierId,

CarrierName,

For OData/SADL scenarios, SAP documentation notes that the first listed text element is treated as the descriptive text.

The annotation does not obtain the text data; the field must already be in the model.


18. @ObjectModel.text.association ​

A different pattern is:

abap
@ObjectModel.text.association: '_Text'
Status

Here, an association provides the text entity.

Current Flight Reference Scenario example:

text
/DMO/I_Travel_Status_VH
        ↓ _Text
/DMO/I_Travel_Status_VH_Text

This is appropriate when the descriptive text lives in a dedicated provider entity.


19. Text element vs text association ​

For one identifier, do not mechanically apply both patterns.

Use:

text
text.element

when descriptive elements are part of the same result entity.

Use:

text
text.association

when a dedicated associated target provides the text relationship.

The exact appropriate pattern also depends on whether the model is an interface view, projection view, value-help provider, and so on.


20. Language-dependent texts ​

The SAP travel-status text example demonstrates:

abap
@Semantics.language: true
Language

and:

abap
@Semantics.text: true
Text

The language key enables language-specific text handling.

In projection/service scenarios, SAP also uses:

text
localized

to retrieve text in the consumer's logon language.

The main Lesson 6 goal is recognition of the text-provider model, not full localized projection syntax.


21. Why value help is not the main Lesson 6 topic ​

Text metadata and value-help metadata often appear together.

SAP Flight examples combine:

text
text elements
text associations
@Consumption.valueHelpDefinition
search annotations
UI text arrangement

The course does not introduce that entire consumption layer here.

Reason:

text
Lesson 6 = semantic data model
Lesson 7 = service exposure
Later FE lesson = UI/value-help consumption

Students should understand ID/text semantics before value-help configuration.


22. Data Preview limitations for semantics ​

Data Preview is excellent for:

text
rows
columns
filters
association navigation

It is not the best place to prove every semantic annotation's effect.

Use:

text
Active Annotations

to inspect metadata.

Later:

text
OData metadata
Fiori Elements

will make additional semantic effects visible.


23. SQL Console and semantic annotations ​

ABAP SQL continues to query CDS elements normally.

No special ABAP SQL syntax is required merely because an element carries amount/currency, quantity/unit, or text metadata.

The metadata becomes relevant to frameworks and operations that interpret those semantics.


24. Practice model design ​

The practice creates:

text
ZI_BOOKING_SEM_###

and applies:

text
FlightPrice → CurrencyCode
CustomerId → CustomerName
CarrierId → CarrierName

It also uses Active Annotations and includes an alias-change exercise.

To avoid making the exercise depend completely on a previous practice artifact, the Companion includes a minimal independent Booking base model.


25. Practice base association reference ​

abap
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Booking Association Base'

define view entity ZI_Booking_Base_###
  as select from /dmo/booking as Booking

    association [1..1] to /DMO/I_Customer as _Customer
      on $projection.CustomerId = _Customer.CustomerID

    association [1..1] to /DMO/I_Carrier as _Carrier
      on $projection.CarrierId = _Carrier.AirlineID

{
  key Booking.travel_id      as TravelId,
  key Booking.booking_id     as BookingId,

      Booking.customer_id    as CustomerId,
      _Customer.LastName     as CustomerName,

      Booking.carrier_id     as CarrierId,
      _Carrier.Name          as CarrierName,

      Booking.connection_id  as ConnectionId,
      Booking.flight_date    as FlightDate,
      Booking.flight_price   as FlightPrice,
      Booking.currency_code  as CurrencyCode,

      _Customer,
      _Carrier
}

26. Practice semantic entity reference ​

abap
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Semantic Booking'
@Metadata.ignorePropagatedAnnotations: true

define view entity ZI_Booking_Sem_###
  as select from ZI_Booking_Base_### as Booking
{
  key Booking.TravelId,
  key Booking.BookingId,

      @ObjectModel.text.element: ['CustomerName']
      Booking.CustomerId,

      Booking.CustomerName,

      @ObjectModel.text.element: ['CarrierName']
      Booking.CarrierId,

      Booking.CarrierName,

      Booking.ConnectionId,
      Booking.FlightDate,

      @Semantics.amount.currencyCode: 'CurrencyCode'
      Booking.FlightPrice,

      Booking.CurrencyCode,

      Booking._Customer,
      Booking._Carrier
}

27. Practice Active Annotations expectations ​

For:

text
FlightPrice

students should find:

text
Semantics.amount.currencyCode
  → CurrencyCode

For:

text
CustomerId

students should find:

text
ObjectModel.text.element
  → CustomerName

For:

text
CarrierId

students should find:

text
ObjectModel.text.element
  → CarrierName

Because propagation is disabled in the semantic layer, these important relationships are intentionally defined locally.

For Practice Part 13, temporarily place this element annotation in the chosen lower booking entity, immediately before its ConnectionId projection:

abap
      @EndUserText.label: 'Booking connection (Lesson 6)'
      Booking.connection_id as ConnectionId,

If the lower model uses a different source alias, retain its existing field projection and add only the label above it. Save any existing element label before replacing it. Activate the lower entity and the semantic entity, then compare Active Annotations on ZI_BOOKING_SEM_###:

State of the semantic entityConnectionId labelFlightPrice amount reference
@Metadata.ignorePropagatedAnnotations: trueThe temporary marker is absentCurrencyCode, origin ZI_BOOKING_SEM_###
Suppression annotation removed, upper entity activated, Active Annotations reopenedBooking connection (Lesson 6), origin the chosen ZI_BOOKING_BASE_### or ZI_BOOKING_ASSOC_###CurrencyCode, origin ZI_BOOKING_SEM_###

The marker must appear in the second state: the exercise deliberately supplies a propagatable annotation. If it does not, check the actual lower source, annotation placement, direct projection without a local label override, activation, and reopening Active Annotations as described in Part 13.

After recording both states, restore suppression in the semantic entity and restore the lower field's original label, or remove only the temporary annotation if there was no label before. Activate the lower entity and then the semantic entity. The submitted model should no longer show the marker upstairs, and the amount reference should remain locally defined.


28. Practice alias-change challenge ​

Rename:

text
CurrencyCode

to:

text
TransactionCurrency

in a higher semantic layer.

Correct amount metadata:

abap
@Semantics.amount.currencyCode: 'TransactionCurrency'
Booking.FlightPrice,

Booking.CurrencyCode as TransactionCurrency

The annotation references the new local element name.

This proves that reference annotations are tied to the local CDS contract.


29. Practice text-provider analysis ​

Students inspect:

text
/DMO/I_TRAVEL_STATUS_VH
/DMO/I_TRAVEL_STATUS_VH_TEXT

Expected findings:

text
text association: _Text
language field: Language
text field: Text

and annotations:

text
@ObjectModel.text.association
@Semantics.language
@Semantics.text

No custom travel-status text entity is required.


30. Troubleshooting ​

Amount annotation references unknown element ​

Check:

text
spelling
case
alias name in current entity
whether the currency element is exposed

Quantity activation complains after propagation is disabled ​

Ensure the quantity has an explicit valid reference:

abap
@Semantics.quantity.unitOfMeasure: 'DistanceUnit'
Distance

and that:

text
DistanceUnit

exists in the same entity.


Active Annotations does not show the latest edit ​

Activate the Data Definition first:

text
Ctrl + F3

Active Annotations displays active metadata.


A propagated annotation disappeared ​

Check for:

abap
@Metadata.ignorePropagatedAnnotations: true

Also check whether the field became an expression or was overridden.


Text annotation does not produce a new field ​

That is expected.

Annotations describe existing fields; they do not create target data.


CarrierName does not exist ​

The semantic annotation cannot invent it.

Make sure the lower association layer exposes CarrierName or retrieve it through the appropriate association/path.


31. Self-review checklist ​

A strong Lesson 6 solution should demonstrate:

  • all required booking fields and associations retained, with TravelId and BookingId declared as keys;
  • correct amount/currency reference;
  • correct quantity/unit reference;
  • no hard-coded currency/unit assumptions;
  • identifier/text relationships modeled deliberately;
  • correct distinction between text element and text association;
  • understanding of language/text semantics;
  • Active Annotations used successfully;
  • propagation behavior explained accurately;
  • the temporary booking label appearing only when propagation is allowed, with its lower origin verified and the original model restored;
  • explicit semantics when propagation is disabled;
  • UI annotations kept out of the core lesson.

32. Current SAP references ​