Skip to content

Lesson 6 — CDS Semantics & Annotations ​

By the end of Lesson 5, your CDS models could describe:

text
fields
calculated values
filters
joins
associations
navigation

But a field's technical type and name do not always communicate its business meaning.

Consider:

text
125.50

Is that:

text
125.50 EUR
125.50 USD
125.50 GBP

Now consider:

text
6210

Is that:

text
6210 KM
6210 MI
6210 M

And consider an identifier:

text
LH

A person may understand it more easily when the model also knows:

text
LH → Lufthansa

This is where CDS annotations and semantics become important.

In this lesson, you will add metadata that describes relationships such as:

text
Amount   → Currency
Quantity → Unit
Code     → Descriptive text

You will also use ADT's Active Annotations view to inspect which annotations are actually active and where they came from.


Lesson information ​

DurationAbout 120–150 minutes
EnvironmentSAP BTP ABAP Trial
Development toolEclipse with ABAP Development Tools (ADT)
PrerequisitesLessons 1–5
Route sourceZI_ROUTE_ASSOC_###
Flight source/DMO/FLIGHT
Semantic route entityZI_ROUTE_SEM_###
Flight price entityZI_FLIGHT_PRICE_###
Text-model examples/DMO/I_CARRIER, /DMO/I_TRAVEL_STATUS_VH, /DMO/I_TRAVEL_STATUS_VH_TEXT

Learning objectives ​

After completing this lesson, you should be able to:

  • explain what a CDS annotation is;
  • distinguish entity-level and element-level annotations;
  • explain the purpose of semantic metadata;
  • connect an amount field to its currency field;
  • connect a quantity field to its unit-of-measure field;
  • explain why amount/currency and quantity/unit are pairs;
  • use @Semantics.amount.currencyCode;
  • use @Semantics.quantity.unitOfMeasure;
  • explain the role of @Semantics.text;
  • explain the role of @ObjectModel.text.element;
  • explain the purpose of a text association;
  • identify language-dependent text metadata;
  • recognize @Semantics.language;
  • inspect active and propagated annotations in ADT;
  • explain annotation propagation through CDS layers;
  • explain what @Metadata.ignorePropagatedAnnotations: true does;
  • know when an annotation must be repeated after renaming or suppressing propagation;
  • keep UI-specific annotations separate from core data-model semantics.

Before you start ​

This lesson reuses the association-based route entity from Lesson 5:

text
ZI_ROUTE_ASSOC_###

If your Lesson 5 object is named differently, substitute that name in the examples.

Replace ### with your own student/group suffix.

Example:

text
ZI_ROUTE_SEM_###     → ZI_ROUTE_SEM_017
ZI_FLIGHT_PRICE_###  → ZI_FLIGHT_PRICE_017

Scope of this lesson

This lesson is about data-model metadata.

It does not teach:

text
@UI.lineItem
@UI.identification
@UI.selectionField
Fiori Elements page design
Metadata Extensions for UI layout

Those concepts belong later, when the course has an actual service/UI consumption layer.


1. What is an annotation? ​

A CDS annotation adds metadata to a CDS object or one of its elements.

Annotations begin with:

text
@

You already used annotations such as:

abap
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Route'

Annotations can describe things such as:

text
labels
authorization behavior
currency relationships
unit relationships
texts
language fields
search behavior
service/UI metadata

The exact effect depends on the annotation and the framework that evaluates it.


2. Annotation scope ​

Annotations are placed where their scope allows them.

Entity/header annotation ​

Placed before:

abap
define view entity

Example:

abap
@EndUserText.label: 'Semantic Route'
define view entity ...

This describes the CDS entity.

Element annotation ​

Placed immediately before the element it describes.

Example:

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

This metadata belongs to:

text
Distance

TIP

The location of an annotation in the source is meaningful.

An annotation before an element usually describes that element, while an entity/header annotation describes the CDS entity.


3. Semantics: more than a data type ​

Suppose the database knows:

text
FlightPrice = numeric amount
CurrencyCode = character field

A consumer still needs to know:

Which currency belongs to this amount?

Similarly:

text
Distance = numeric quantity
DistanceUnit = unit key

needs:

Which unit belongs to this quantity?

CDS semantic annotations describe those relationships explicitly.


4. Inspect SAP's Flight CDS example ​

Open:

text
/DMO/I_FLIGHT

using:

text
Ctrl + Shift + A

Find the price fields.

Current SAP Flight Reference Scenario code uses:

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

Flight.currency_code as CurrencyCode,

The annotation means:

text
Price
  ↓ currency reference
CurrencyCode

It does not mean:

text
Price is always EUR

The currency can differ per row.


5. Amount + currency ​

The pattern is:

abap
@Semantics.amount.currencyCode: 'CurrencyCode'
<amount expression> as Amount,

<currency expression> as CurrencyCode

The annotation value:

text
'CurrencyCode'

is the name of the CDS element that contains the currency key for the amount.

The relationship is:

text
Amount
   │
   └── uses currency from → CurrencyCode

6. Create ZI_FLIGHT_PRICE_### ​

Create a new Data Definition.

Step 6.1 — Open the wizard ​

Right-click your package:

text
New
  → Other ABAP Repository Object
  → Core Data Services
  → Data Definition

Choose Next.

Step 6.2 — Enter details ​

Use:

text
Name:        ZI_FLIGHT_PRICE_###
Description: Lesson 6 - Flight Price Semantics

If Referenced Object is available, enter:

text
/DMO/FLIGHT

Choose the course transport if required.

Choose a CDS View Entity template.

Confirm:

abap
define view entity

Choose Finish.


7. Build the Flight Price entity ​

Enter:

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
}

Replace ###.

Check:

text
Ctrl + F2

Activate:

text
Ctrl + F3

Preview:

text
F8

8. What changed in Data Preview? ​

The row values may look almost the same as before.

That is expected.

Annotations usually add metadata, not extra data rows.

The CDS result still contains:

text
Price
CurrencyCode

But the active CDS metadata now describes:

text
Price → CurrencyCode

This metadata becomes important to frameworks and consumers that understand CDS semantics.


9. Do we need @Semantics.currencyCode: true here? ​

In older CDS examples you may see:

abap
@Semantics.currencyCode: true
CurrencyCode

For current CDS View Entities, SAP's RAP documentation explicitly notes that you do not need to repeat the currency-code annotation when the field is already defined as the currency field in the underlying database table.

The essential annotation in this model is:

abap
@Semantics.amount.currencyCode: 'CurrencyCode'
Price

NOTE

You can still encounter @Semantics.currencyCode in other CDS contexts and older examples.

The course follows the current View Entity pattern used by SAP's Flight Reference Scenario.


10. Inspect SAP's Connection CDS example ​

Open:

text
/DMO/I_CONNECTION

Find:

text
Distance
DistanceUnit

Current SAP Flight Reference Scenario code uses:

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

Connection.distance_unit as DistanceUnit

The relationship is:

text
Distance
   │
   └── uses unit from → DistanceUnit

11. Quantity + unit ​

The general pattern is:

abap
@Semantics.quantity.unitOfMeasure: 'UnitElement'
<quantity> as Quantity,

<unit> as UnitElement

Examples:

text
Distance → DistanceUnit
Weight   → WeightUnit
Length   → LengthUnit

The value:

text
'DistanceUnit'

is a CDS element reference, not a hard-coded unit such as:

text
'KM'

Different rows can use different units.


12. Add a semantic layer to the Route model ​

Lesson 5 created:

text
ZI_ROUTE_ASSOC_###

It already exposes:

text
CarrierId
CarrierName
OriginAirportId
OriginAirportName
DestinationAirportId
DestinationAirportName
Distance
DistanceUnit
...

Create a new Data Definition:

text
ZI_ROUTE_SEM_###

Description:

text
Lesson 6 - Semantic Route

Use:

text
ZI_ROUTE_ASSOC_###

as the source.


13. Why create another layer? ​

We could edit the Lesson 5 entity directly.

Instead, this lesson creates:

text
ZI_ROUTE_ASSOC_###
      ↓
ZI_ROUTE_SEM_###

This makes annotation layering visible.

It also gives us a concrete way to inspect:

text
local annotations
propagated annotations
annotation origin

in ADT.


14. Build the semantic Route entity ​

Replace the generated source with the complete definition below. For this first version, leave out @Metadata.ignorePropagatedAnnotations: true if your wizard inserted it. We will add it deliberately in Section 20 so we can compare propagation before and after.

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

define view entity ZI_Route_Sem_###
  as select from ZI_Route_Assoc_### as Route
{
  key Route.CarrierId,
  key Route.ConnectionId,

      Route.CarrierName,

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

      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
}

Replace ###.

Check and activate.


15. Verify the quantity semantics ​

Open Data Preview:

text
F8

The data still shows:

text
Distance
DistanceUnit

The important change is metadata:

text
Distance → DistanceUnit

Now inspect that metadata directly.


16. Open Active Annotations in ADT ​

This is a new tool workflow.

Step 16.1 — Activate the CDS entity ​

The Data Definition must have an active version.

Use:

text
Ctrl + F3

Step 16.2 — Open Active Annotations ​

In Project Explorer:

  1. find ZI_ROUTE_SEM_###;
  2. right-click it;
  3. choose:
text
Open With
  → Active Annotations

You can also open this from the CDS editor context menu.

Step 16.3 — Find Distance ​

Expand or search for:

text
Distance

Look for:

text
Semantics.quantity.unitOfMeasure

The value should reference:

text
DistanceUnit

Step 16.4 — Inspect origin ​

On the annotation row under Distance, read Annotation Value and Origin Data Source. The expected result is:

ElementAnnotationAnnotation ValueOrigin Data Source
DistanceSemantics.quantity.unitOfMeasureDistanceUnitZI_ROUTE_SEM_###

Use your suffix when comparing the object name. ADT may display a different capitalization or append the object type in brackets.

The origin is ZI_ROUTE_SEM_### because you wrote this annotation directly in that entity. Although the distance values come from the lower model, this particular annotation is local to the semantic layer.

Double-click the origin object name to open its source, then find the annotation immediately above Route.Distance. This connects the metadata row to the code that defines it. SAP's Active Annotations documentation describes these columns and navigation.

Checkpoint

You have verified the quantity semantics when you can point to the Distance annotation, its DistanceUnit value, and its origin in your semantic entity.

If the row is missing or still shows an earlier edit, activate the correct Data Definition with Ctrl + F3, then reopen Active Annotations. In the tree display, expand the annotation groups under Distance; the full name may be split across those groups.


17. Annotation propagation ​

CDS element annotations can be inherited from underlying data sources.

Conceptually:

text
Lower CDS entity
   @SomeAnnotation
        ↓
Higher CDS entity
        ↓
annotation may propagate

But propagation has rules.

It is not correct to assume:

Every annotation always propagates through every CDS layer.

Propagation can be:

text
allowed
overridden
stopped
broken by expressions
disabled for the entity

18. @Metadata.ignorePropagatedAnnotations ​

A CDS entity can use:

abap
@Metadata.ignorePropagatedAnnotations: true

This disables annotation propagation from lower CDS layers for that entity.

Example:

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

define view entity ...

Current SAP documentation notes that this setting is included in the standard View Entity template and is set to true by default there.

Its purpose is stability:

text
a lower-layer annotation change
does not silently change a higher consumer layer

19. Why explicit semantics still matter ​

If propagation is disabled:

text
lower-layer semantics
      ✕
higher layer

important semantic references may need to be stated again.

That is why a stable consumer/model layer often repeats important semantic relationships explicitly:

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

or:

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

20. Try the propagation switch ​

We will track a temporary element label from the lower Route entity. This gives us one known annotation to compare, alongside the quantity annotation already defined locally.

Step 20.1 — Add a known annotation to the lower entity ​

Open ZI_ROUTE_ASSOC_###, the source of your semantic Route entity. Find the existing projection of Connection.distance and add the label immediately above it:

abap
      @EndUserText.label: 'Route distance (Lesson 6)'
      Connection.distance         as Distance,
      Connection.distance_unit    as DistanceUnit,

Edit the existing field; do not add a second Distance field. If it already has an element-level @EndUserText.label, note its original value and temporarily replace that label. Keep any other annotations on the field.

The label belongs inside the element list, directly above Distance. Changing the entity's header label would label the whole view and would not demonstrate element-annotation propagation.

Activate ZI_ROUTE_ASSOC_###.

Step 20.2 — Observe propagation enabled ​

Open ZI_ROUTE_SEM_###. Confirm that its header has no @Metadata.ignorePropagatedAnnotations: true and that you have not added a local label to Route.Distance. Keep its explicit quantity annotation.

Activate the semantic entity, reopen its Active Annotations view, and inspect Distance:

ElementAnnotationAnnotation ValueOrigin Data Source
DistanceEndUserText.labelRoute distance (Lesson 6)ZI_ROUTE_ASSOC_###
DistanceSemantics.quantity.unitOfMeasureDistanceUnitZI_ROUTE_SEM_###

Both annotations describe the same field, but their origins differ: the label is inherited, while the quantity relationship is local.

Step 20.3 — Stop propagation and compare ​

Add @Metadata.ignorePropagatedAnnotations: true to the header of ZI_ROUTE_SEM_###:

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

Activate it and reopen Active Annotations for the semantic entity.

Check under DistancePropagation enabledPropagation disabled
Test label Route distance (Lesson 6) from ZI_ROUTE_ASSOC_###PresentNo longer inherited
Quantity reference DistanceUnit from ZI_ROUTE_SEM_###PresentStill present

The switch controls inherited annotations. It does not remove annotations written in the current entity, and it does not remove the Distance data column. These are the propagation and local-override rules described in SAP's propagation documentation.

If your result differs

If the test label never appears with propagation enabled, first inspect Distance in the lower entity's Active Annotations. Confirm its label is Route distance (Lesson 6), activate both entities in source-to-consumer order, and check that the upper entity selects from that exact lower entity.

If the test label remains after disabling propagation, check its Origin Data Source. A copy placed locally in ZI_ROUTE_SEM_### will remain active. Remove only that accidental local test label, check that the header switch is true, then activate and reopen the view.

Step 20.4 — Restore the lower model ​

Remove only the temporary label from ZI_ROUTE_ASSOC_###, or restore its original element label if you replaced one. Activate the lower entity and then the semantic entity.

Keep @Metadata.ignorePropagatedAnnotations: true in the semantic entity and keep @Semantics.quantity.unitOfMeasure: 'DistanceUnit' on its Distance field. This is the state used by the remaining sections and the complete reference model.

Before continuing, explain why the inherited label disappeared while the quantity reference remained.


21. Expressions can interrupt propagation ​

When an element becomes the result of an expression, source annotations do not automatically behave as though the element were a direct pass-through field.

Examples include:

text
arithmetic expressions
CASE
CAST
other calculations

This matters when calculated data is still an:

text
amount
quantity
date/time semantic value

The calculated result may need its own correct semantic annotation.

Do not assume:

text
source is an amount
therefore every expression using it is automatically an amount

The semantics of the result must be modeled correctly.


22. Element aliases can require renewed references ​

Suppose a lower entity has:

text
Price
CurrencyCode

and a higher layer renames:

text
CurrencyCode → TransactionCurrency

Then an amount annotation that refers to:

text
'CurrencyCode'

cannot keep pointing to the old local name.

The higher layer may need:

abap
@Semantics.amount.currencyCode: 'TransactionCurrency'
Price,

Current SAP projection-view documentation explicitly calls out this kind of re-annotation when the referenced currency/unit field name changes.


23. Human-readable text metadata ​

Identifiers are excellent for:

text
keys
relationships
filtering
storage

but not always ideal for people.

Examples:

text
LH → Lufthansa
FRA → Frankfurt Airport

A CDS model can express a relationship between an identifier and a descriptive text.

One common pattern when both are in the same entity is:

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

CarrierName,

This says:

text
CarrierName is descriptive text for CarrierId

Read the annotation syntax ​

Read @ObjectModel.text.element: ['CarrierName'] from left to right: @ starts an annotation, the dotted name identifies the annotation and its subparts, and : introduces its value. The square brackets contain a list, also called an annotation array. Here that list has one item: the name of the descriptive element.

Compare the value forms used in this lesson:

ExampleHow to read the value
@Semantics.amount.currencyCode: 'CurrencyCode'A single quoted element name: use the currency key from this field in each row.
@ObjectModel.text.element: ['CarrierName']A list containing one element name. Keep the brackets even when there is only one item.
@Metadata.ignorePropagatedAnnotations: trueA Boolean value: true or false, written without quotes.
@AccessControl.authorizationCheck: #NOT_REQUIREDA predefined choice, called an enumeration value. The # introduces that choice.
@EndUserText.label: 'Semantic Route'Literal label text to display, rather than the name of another field.

The annotation's definition determines which value form is allowed; they are not interchangeable. Quoted text can therefore mean a field reference or a label depending on the annotation. SAP explains the general rules in Using Annotations.

Quick check

Why is ['CarrierName'] a list while 'CurrencyCode' is a single name? Because these two annotations define different value types. In both examples, the named field must be exposed by the entity being annotated.


24. Add Carrier text metadata ​

In ZI_ROUTE_SEM_###, place this annotation before CarrierId:

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

The beginning of the element list becomes:

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

  key Route.ConnectionId,

      Route.CarrierName,
      ...
}

Activate.

Open Active Annotations.

Inspect:

text
CarrierId

and locate:

text
ObjectModel.text.element

25. Add Airport text metadata ​

Add:

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

Route.OriginAirportName,

and:

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

Route.DestinationAirportName,

Now your semantic model says:

text
CarrierId            → CarrierName
OriginAirportId      → OriginAirportName
DestinationAirportId → DestinationAirportName

26. Complete semantic Route model ​

A complete version is:

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
}

Activate and inspect Active Annotations.


27. @Semantics.text ​

@ObjectModel.text.element says:

text
this identifier uses this element as its descriptive text

A text-provider entity can separately mark an element as:

text
this field is text

using:

abap
@Semantics.text: true

Open:

text
/DMO/I_CARRIER

Find:

abap
@Semantics.text: true
Airline.name as Name

This identifies Name as a human-readable text element.


28. Same-entity text vs text provider ​

There are two related ideas.

Descriptive element in the consuming entity ​

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

CarrierName,

This connects an ID and a descriptive element available in the same result entity.

Text provider ​

A target/model can mark:

abap
@Semantics.text: true
Name

to identify a field as text.

These concepts often work together in layered CDS/service models.


29. Language-dependent texts ​

Some descriptions need translation.

For example:

text
status code
  ↓
English text
German text
Portuguese text
...

A language-dependent text provider generally needs:

text
code
language
text

and semantic metadata identifying:

text
language field
text field

SAP's Flight Reference Scenario includes a good existing example.


30. Inspect /DMO/I_TRAVEL_STATUS_VH ​

Open:

text
/DMO/I_TRAVEL_STATUS_VH

Find the status element and its text association.

Current SAP example uses:

abap
@ObjectModel.text.association: '_Text'
key travel_status as TravelStatus,

and exposes:

text
_Text

This says that the associated entity provides descriptive texts for the status.


31. Inspect the Text target ​

Open:

text
/DMO/I_TRAVEL_STATUS_VH_TEXT

Find:

text
TravelStatus
Language
Text

Current SAP example marks:

abap
@Semantics.language: true
language as Language

and:

abap
@Semantics.text: true
text as Text

The model therefore knows:

text
Language = language key
Text     = descriptive text

32. Text association model ​

Conceptually:

text
TravelStatus entity
       │
       │ @ObjectModel.text.association
       ▼
     _Text
       │
       ▼
TravelStatus Text entity
  ├─ Status
  ├─ Language
  └─ Text

This is different from simply joining one text column into one fixed result.

The text relationship remains modeled.


33. @ObjectModel.text.element vs text.association ​

Do not use the names interchangeably.

@ObjectModel.text.element ​

Links an identifier to one or more descriptive elements available in the entity.

Example:

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

@ObjectModel.text.association ​

Points an identifier to an association that provides its text.

Example concept:

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

SAP documentation notes that these are alternative text-modeling patterns for the same annotated identifier; do not blindly apply both to one field.


34. Annotations do not replace associations ​

This:

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

does not fetch CarrierName.

The field must already exist in the entity.

In our model it exists because Lesson 5 already provided:

text
_Carrier.Name → CarrierName

So:

text
association/path
=
obtain/relate data

annotation
=
describe the meaning of that data

This distinction is essential.


35. Annotations do not usually change SQL row selection ​

Adding:

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

does not normally add or remove rows.

It describes the model.

By contrast:

text
JOIN
WHERE
CASE
arithmetic expression

can directly affect the result data or row structure.


36. Use code completion for annotations ​

ADT helps with annotation names.

In a CDS editor:

  1. place the cursor before an element;
  2. type:
text
@

or part of an annotation, such as:

text
@Semantics
  1. press:
text
Ctrl + Space

Inspect the completion list.

This is safer than memorizing every annotation spelling.


37. Use F1 documentation ​

Place the cursor on an annotation such as:

abap
@Semantics.amount.currencyCode

Use ADT context help/F1 where available.

Annotations have properties such as:

text
scope
type
allowed values
evaluation runtime

When you encounter a new annotation later, check its documentation instead of guessing its behavior.


38. Active Annotations vs source code ​

Source code shows what you wrote locally.

Active Annotations can show:

text
local annotations
inherited annotations
active values
origin data source
origin data element

That is especially valuable in layered CDS models.

Use it whenever you ask:

Where did this annotation come from?


39. Data Preview vs Active Annotations ​

Data Preview ​

Answers:

text
What rows and columns does this CDS entity return?

Active Annotations ​

Answers:

text
What metadata is active?
What is its value?
Where did it originate?

Both are needed for modern CDS development.


40. SQL Console still sees the data ​

Query your semantic route entity:

abap
SELECT FROM zi_route_sem_###
  FIELDS CarrierId,
         CarrierName,
         OriginAirportId,
         OriginAirportName,
         DestinationAirportId,
         DestinationAirportName,
         Distance,
         DistanceUnit
  ORDER BY CarrierId,
           ConnectionId

The SQL result remains ordinary data.

ABAP SQL does not need special selection syntax merely because the CDS fields carry semantic annotations.

The metadata is available to frameworks/consumers that interpret it.


41. Query Flight Price ​

In SQL Console:

abap
SELECT FROM zi_flight_price_###
  FIELDS CarrierId,
         ConnectionId,
         FlightDate,
         Price,
         CurrencyCode
  ORDER BY CarrierId,
           ConnectionId,
           FlightDate

Again:

text
rows remain rows
fields remain fields
semantic metadata describes how fields belong together

42. Why semantic metadata matters for services ​

Later, when CDS models are exposed through RAP/SADL/OData, semantic annotations can be translated into corresponding service metadata.

For example:

text
amount ↔ currency

and:

text
quantity ↔ unit

can be understood by supported consumers.

That is one reason semantic metadata belongs in the data model rather than being recreated in every UI.


43. Why we are not adding UI annotations yet ​

A future Fiori Elements lesson will cover:

text
@UI.lineItem
@UI.identification
@UI.selectionField
facets
metadata extensions

Those annotations describe presentation/interaction.

This lesson focuses on meaning that remains useful independently of one specific UI:

text
this number is an amount
this field provides its currency
this number is a quantity
this field provides its unit
this ID has a descriptive text
this field is a language key

44. Common mistakes ​

Hard-coding a currency in the annotation ​

Wrong idea:

text
Price is always EUR

The annotation references a currency element:

abap
@Semantics.amount.currencyCode: 'CurrencyCode'

Referencing a field that is not exposed ​

This is invalid modeling:

abap
@Semantics.amount.currencyCode: 'CurrencyCode'
Price

if:

text
CurrencyCode

is not available in the entity.


Renaming the reference field but keeping the old annotation target ​

If:

text
CurrencyCode → TransactionCurrency

then:

text
'CurrencyCode'

may need to become:

text
'TransactionCurrency'

Treating @ObjectModel.text.element as data retrieval ​

It does not fetch the text field.

The descriptive field must exist in the entity.


Applying both text-element and text-association patterns blindly ​

Choose the pattern that matches the model.

Understand what the text source actually is.


Assuming all annotations always propagate ​

Propagation has rules and can be disabled.

Use:

text
Active Annotations

to inspect the real active metadata.


Copying @Metadata.ignorePropagatedAnnotations: true without understanding it ​

This annotation deliberately stops propagation.

It may require important semantic references to be repeated locally.


Putting @UI.* annotations into every core interface model immediately ​

Keep semantic data-model metadata separate from presentation metadata unless there is a clear architectural reason.


45. Knowledge check ​

1. What does @Semantics.amount.currencyCode do? ​

Show answer

It identifies the CDS element that contains the currency key for an amount element.

2. Does it hard-code one currency? ​

Show answer

No. It references another CDS element whose value can vary per row.

3. What does @Semantics.quantity.unitOfMeasure do? ​

Show answer

It links a quantity element to the CDS element that contains its unit-of-measure key.

4. What does @ObjectModel.text.element: ['CarrierName'] on CarrierId mean? ​

Show answer

It states that CarrierName is a descriptive text element for CarrierId.

5. What does @Semantics.text: true mean? ​

Show answer

It identifies an element as human-readable text.

6. What does @Semantics.language: true identify? ​

Show answer

The element that carries the language key used for language-dependent text handling.

7. What does @Metadata.ignorePropagatedAnnotations: true do? ​

Show answer

It disables annotation propagation from lower data sources into that CDS entity.

8. Why can a semantic annotation need to be repeated after renaming a reference field? ​

Show answer

Because the annotation refers to the CDS element name that contains the currency/unit. If that name changes in the new layer, the reference must point to the new element name.

9. What does Active Annotations show that source code alone may not? ​

Show answer

It shows the annotations that are actually active, including propagated values and their origins.

10. Does @ObjectModel.text.element replace an association/path that obtains the text? ​

Show answer

No. The text data still has to be present in the entity. The annotation describes its relationship to the identifier.


46. Lesson summary ​

You added business meaning to CDS fields and relationships.

You worked with:

text
annotations
annotation scope
amount ↔ currency
quantity ↔ unit
identifier ↔ text
text providers
language-dependent text
annotation propagation
@Metadata.ignorePropagatedAnnotations
Active Annotations

The semantic relationships now include:

text
Price
  └── CurrencyCode

Distance
  └── DistanceUnit

CarrierId
  └── CarrierName

OriginAirportId
  └── OriginAirportName

DestinationAirportId
  └── DestinationAirportName

The central idea is:

CDS annotations describe the meaning and metadata of a data model so supported consumers do not have to rediscover those relationships independently.


47. What comes next? ​

Before moving on, complete the Lesson 6 practice assignment to add semantic metadata to booking data. Use the Lesson 6 companion for deeper explanations, troubleshooting, and reference implementations.

You now have the major CDS foundation:

text
view entities
expressions
filters
joins
associations
semantics
annotations

Lesson 7 — CDS Aggregation, GROUP BY, HAVING & Code Pushdown shows how to summarize detailed rows in the database and consume the results from ABAP:

text
Detailed flight or booking rows
   ↓
GROUP BY
   ↓
COUNT / SUM / AVG / MIN / MAX
   ↓
HAVING
   ↓
Summarized CDS result
   ↓
Reader → Runner

You will decide what one summary row represents, distinguish filtering individual rows with WHERE from filtering groups with HAVING, and see how database aggregation puts code pushdown into practice.

The booking practice builds directly on this lesson's amount/currency semantics: monetary totals must retain their currency reference and keep different currencies in separate groups.