Appearance
Lesson 6 — CDS Semantics & Annotations
By the end of Lesson 5, your CDS models could describe:
text
fields
calculated values
filters
joins
associations
navigationBut a field's technical type and name do not always communicate its business meaning.
Consider:
text
125.50Is that:
text
125.50 EUR
125.50 USD
125.50 GBPNow consider:
text
6210Is that:
text
6210 KM
6210 MI
6210 MAnd consider an identifier:
text
LHA person may understand it more easily when the model also knows:
text
LH → LufthansaThis 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 textYou will also use ADT's Active Annotations view to inspect which annotations are actually active and where they came from.
Lesson information
| Duration | About 120–150 minutes |
| Environment | SAP BTP ABAP Trial |
| Development tool | Eclipse with ABAP Development Tools (ADT) |
| Prerequisites | Lessons 1–5 |
| Route source | ZI_ROUTE_ASSOC_### |
| Flight source | /DMO/FLIGHT |
| Semantic route entity | ZI_ROUTE_SEM_### |
| Flight price entity | ZI_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: truedoes; - 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_017Scope 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 layoutThose 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 metadataThe 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 entityExample:
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
DistanceTIP
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 fieldA consumer still needs to know:
Which currency belongs to this amount?
Similarly:
text
Distance = numeric quantity
DistanceUnit = unit keyneeds:
Which unit belongs to this quantity?
CDS semantic annotations describe those relationships explicitly.
4. Inspect SAP's Flight CDS example
Open:
text
/DMO/I_FLIGHTusing:
text
Ctrl + Shift + AFind 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
CurrencyCodeIt does not mean:
text
Price is always EURThe currency can differ per row.
5. Amount + currency
The pattern is:
abap
@Semantics.amount.currencyCode: 'CurrencyCode'
<amount expression> as Amount,
<currency expression> as CurrencyCodeThe 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 → CurrencyCode6. 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 DefinitionChoose Next.
Step 6.2 — Enter details
Use:
text
Name: ZI_FLIGHT_PRICE_###
Description: Lesson 6 - Flight Price SemanticsIf Referenced Object is available, enter:
text
/DMO/FLIGHTChoose the course transport if required.
Choose a CDS View Entity template.
Confirm:
abap
define view entityChoose 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 + F2Activate:
text
Ctrl + F3Preview:
text
F88. 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
CurrencyCodeBut the active CDS metadata now describes:
text
Price → CurrencyCodeThis 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
CurrencyCodeFor 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'
PriceNOTE
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_CONNECTIONFind:
text
Distance
DistanceUnitCurrent SAP Flight Reference Scenario code uses:
abap
@Semantics.quantity.unitOfMeasure: 'DistanceUnit'
Connection.distance as Distance,
Connection.distance_unit as DistanceUnitThe relationship is:
text
Distance
│
└── uses unit from → DistanceUnit11. Quantity + unit
The general pattern is:
abap
@Semantics.quantity.unitOfMeasure: 'UnitElement'
<quantity> as Quantity,
<unit> as UnitElementExamples:
text
Distance → DistanceUnit
Weight → WeightUnit
Length → LengthUnitThe 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 RouteUse:
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 originin 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
F8The data still shows:
text
Distance
DistanceUnitThe important change is metadata:
text
Distance → DistanceUnitNow 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 + F3Step 16.2 — Open Active Annotations
In Project Explorer:
- find
ZI_ROUTE_SEM_###; - right-click it;
- choose:
text
Open With
→ Active AnnotationsYou can also open this from the CDS editor context menu.
Step 16.3 — Find Distance
Expand or search for:
text
DistanceLook for:
text
Semantics.quantity.unitOfMeasureThe value should reference:
text
DistanceUnitStep 16.4 — Inspect origin
On the annotation row under Distance, read Annotation Value and Origin Data Source. The expected result is:
| Element | Annotation | Annotation Value | Origin Data Source |
|---|---|---|---|
Distance | Semantics.quantity.unitOfMeasure | DistanceUnit | ZI_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 propagateBut 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 entity18. @Metadata.ignorePropagatedAnnotations
A CDS entity can use:
abap
@Metadata.ignorePropagatedAnnotations: trueThis 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 layer19. Why explicit semantics still matter
If propagation is disabled:
text
lower-layer semantics
✕
higher layerimportant 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:
| Element | Annotation | Annotation Value | Origin Data Source |
|---|---|---|---|
Distance | EndUserText.label | Route distance (Lesson 6) | ZI_ROUTE_ASSOC_### |
Distance | Semantics.quantity.unitOfMeasure | DistanceUnit | ZI_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: trueActivate it and reopen Active Annotations for the semantic entity.
Check under Distance | Propagation enabled | Propagation disabled |
|---|---|---|
Test label Route distance (Lesson 6) from ZI_ROUTE_ASSOC_### | Present | No longer inherited |
Quantity reference DistanceUnit from ZI_ROUTE_SEM_### | Present | Still 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 calculationsThis matters when calculated data is still an:
text
amount
quantity
date/time semantic valueThe 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 amountThe semantics of the result must be modeled correctly.
22. Element aliases can require renewed references
Suppose a lower entity has:
text
Price
CurrencyCodeand a higher layer renames:
text
CurrencyCode → TransactionCurrencyThen 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
storagebut not always ideal for people.
Examples:
text
LH → Lufthansa
FRA → Frankfurt AirportA 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 CarrierIdRead 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:
| Example | How 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: true | A Boolean value: true or false, written without quotes. |
@AccessControl.authorizationCheck: #NOT_REQUIRED | A 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
CarrierIdand locate:
text
ObjectModel.text.element25. 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 → DestinationAirportName26. 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 textA text-provider entity can separately mark an element as:
text
this field is textusing:
abap
@Semantics.text: trueOpen:
text
/DMO/I_CARRIERFind:
abap
@Semantics.text: true
Airline.name as NameThis 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
Nameto 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
textand semantic metadata identifying:
text
language field
text fieldSAP's Flight Reference Scenario includes a good existing example.
30. Inspect /DMO/I_TRAVEL_STATUS_VH
Open:
text
/DMO/I_TRAVEL_STATUS_VHFind the status element and its text association.
Current SAP example uses:
abap
@ObjectModel.text.association: '_Text'
key travel_status as TravelStatus,and exposes:
text
_TextThis says that the associated entity provides descriptive texts for the status.
31. Inspect the Text target
Open:
text
/DMO/I_TRAVEL_STATUS_VH_TEXTFind:
text
TravelStatus
Language
TextCurrent SAP example marks:
abap
@Semantics.language: true
language as Languageand:
abap
@Semantics.text: true
text as TextThe model therefore knows:
text
Language = language key
Text = descriptive text32. Text association model
Conceptually:
text
TravelStatus entity
│
│ @ObjectModel.text.association
▼
_Text
│
▼
TravelStatus Text entity
├─ Status
├─ Language
└─ TextThis 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'
StatusSAP 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']
CarrierIddoes not fetch CarrierName.
The field must already exist in the entity.
In our model it exists because Lesson 5 already provided:
text
_Carrier.Name → CarrierNameSo:
text
association/path
=
obtain/relate data
annotation
=
describe the meaning of that dataThis distinction is essential.
35. Annotations do not usually change SQL row selection
Adding:
abap
@ObjectModel.text.element
@Semantics.quantity.unitOfMeasure
@Semantics.amount.currencyCodedoes not normally add or remove rows.
It describes the model.
By contrast:
text
JOIN
WHERE
CASE
arithmetic expressioncan directly affect the result data or row structure.
36. Use code completion for annotations
ADT helps with annotation names.
In a CDS editor:
- place the cursor before an element;
- type:
text
@or part of an annotation, such as:
text
@Semantics- press:
text
Ctrl + SpaceInspect 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.currencyCodeUse ADT context help/F1 where available.
Annotations have properties such as:
text
scope
type
allowed values
evaluation runtimeWhen 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 elementThat 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,
ConnectionIdThe 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,
FlightDateAgain:
text
rows remain rows
fields remain fields
semantic metadata describes how fields belong together42. 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 ↔ currencyand:
text
quantity ↔ unitcan 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 extensionsThose 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 key44. Common mistakes
Hard-coding a currency in the annotation
Wrong idea:
text
Price is always EURThe 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'
Priceif:
text
CurrencyCodeis not available in the entity.
Renaming the reference field but keeping the old annotation target
If:
text
CurrencyCode → TransactionCurrencythen:
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 Annotationsto 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 AnnotationsThe semantic relationships now include:
text
Price
└── CurrencyCode
Distance
└── DistanceUnit
CarrierId
└── CarrierName
OriginAirportId
└── OriginAirportName
DestinationAirportId
└── DestinationAirportNameThe 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
annotationsLesson 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 → RunnerYou 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.