Skip to content

Lesson 6 Practice — Semantic Booking Model ​

In Lesson 6 — CDS Semantics & Annotations, you added business meaning to CDS fields and relationships. In this practice, you will apply those concepts to booking data.

Your target model is:

text
Booking
  ├─ CustomerId → CustomerName
  ├─ CarrierId  → CarrierName
  └─ FlightPrice → CurrencyCode

You will also use:

text
Active Annotations

and inspect SAP's language-dependent travel-status text model.


Objects ​

Create:

text
ZI_BOOKING_BASE_###
ZI_BOOKING_SEM_###

If you already completed the Lesson 5 practice assignment and have:

text
ZI_BOOKING_ASSOC_###

you may reuse it instead of creating ZI_BOOKING_BASE_###, provided it exposes the fields required below.

Reusing the Lesson 5 model

The standard Lesson 5 solution exposes CustomerLastName, not CustomerName. When creating ZI_BOOKING_SEM_###, project CustomerLastName as CustomerName, or keep the original name and update the text annotation reference consistently. The examples below use CustomerName.

Replace ### with your suffix.


Part 1 — Inspect the amount source ​

Open:

text
/DMO/BOOKING

Find:

text
flight_price
currency_code

Open Data Preview.

Record one booking:

text
Flight price:
Currency code:

Answer:

Why is FlightPrice ambiguous without CurrencyCode?


Part 2 — Inspect SAP's reference booking CDS ​

Open one of the SAP Flight Reference booking CDS entities available in your tenant, for example:

text
/DMO/I_BOOKING_U

or the corresponding current booking model in the demo package.

Find the price annotation.

Record the annotation name:

text
________________________________________

Record the referenced element:

text
________________________________________

Part 3 — Create the base association model ​

If you are not reusing your Lesson 5 booking entity, create:

text
ZI_BOOKING_BASE_###

Use:

text
/DMO/BOOKING

as the source.

Add associations to:

text
/DMO/I_CUSTOMER
/DMO/I_CARRIER

Your base model must expose:

text
TravelId
BookingId
CustomerId
CustomerName
CarrierId
CarrierName
ConnectionId
FlightDate
FlightPrice
CurrencyCode
_Customer
_Carrier

Use:

text
_Customer.LastName

for CustomerName.

Use:

text
_Carrier.Name

for CarrierName.

Activate and preview.


Part 4 — Create ZI_BOOKING_SEM_### ​

Create a new Data Definition:

text
Name:        ZI_BOOKING_SEM_###
Description: Lesson 6 - Semantic Booking

Source:

text
ZI_BOOKING_BASE_###

or your compatible Lesson 5 booking entity.

In the select list, retain all ten scalar fields (value columns) and both associations listed in Part 3:

text
TravelId          (key)
BookingId         (key)
CustomerId
CustomerName
CarrierId
CarrierName
ConnectionId
FlightDate
FlightPrice
CurrencyCode
_Customer
_Carrier

Declare TravelId and BookingId with key in this entity too. The later SQL exercises select and order by these identifiers. Parts 5–7 add metadata to fields in this list; do not add duplicate projections of those fields.

If you reuse the Lesson 5 entity, project CustomerLastName as CustomerName here to match this list and the examples in Part 6. If you choose to keep CustomerLastName as allowed above, retain that field in place of CustomerName and use its name consistently in the text annotation and your checks.

Add:

abap
@Metadata.ignorePropagatedAnnotations: true

to the CDS header.


Part 5 — Add amount/currency semantics ​

Expose:

text
FlightPrice
CurrencyCode

Add the semantic annotation to:

text
FlightPrice

It must reference:

text
CurrencyCode

Do not hard-code:

text
EUR
USD
GBP
Hint

The annotation starts with:

abap
@Semantics.amount.currencyCode:

Part 6 — Add Customer text metadata ​

Expose:

text
CustomerId
CustomerName

Annotate:

text
CustomerId

so that:

text
CustomerName

is defined as its descriptive text element.

Hint

Use:

abap
@ObjectModel.text.element: [...]

Part 7 — Add Carrier text metadata ​

Expose:

text
CarrierId
CarrierName

Define:

text
CarrierName

as the text element for:

text
CarrierId

Part 8 — Activate and preview ​

Run:

text
Ctrl + F2

Activate:

text
Ctrl + F3

Open Data Preview:

text
F8

Confirm the data still contains normal scalar columns.

Answer:

Why does semantic metadata not necessarily create a visibly different row result in Data Preview?


Part 9 — Open Active Annotations ​

Right-click:

text
ZI_BOOKING_SEM_###

Choose:

text
Open With
  → Active Annotations

Find:

text
FlightPrice

Record:

text
Annotation:
Value:
Origin:

Part 10 — Inspect CustomerId annotations ​

In Active Annotations, find:

text
CustomerId

Record the text-related active annotation and its value.

Expected relationship:

text
CustomerId → CustomerName

Part 11 — Inspect CarrierId annotations ​

Repeat for:

text
CarrierId

Expected relationship:

text
CarrierId → CarrierName

Part 12 — Explain propagation suppression ​

Your semantic entity contains:

abap
@Metadata.ignorePropagatedAnnotations: true

Answer:

What does this annotation do? ​

Why are the amount and text relationships defined explicitly in this entity? ​

What advantage can this give a higher consumer layer? ​


Part 13 — Propagation experiment ​

Use a temporary label as a known marker so that the result does not depend on metadata supplied by your tenant.

13.1 Add a marker to the lower entity ​

Open the entity used in the as select from clause of ZI_BOOKING_SEM_###: either ZI_BOOKING_BASE_### or your reused ZI_BOOKING_ASSOC_###.

Find the projection of ConnectionId. If it already has an element-level @EndUserText.label, copy that original annotation into your notes before replacing it temporarily. Otherwise, add the annotation immediately above the field:

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

This is inside the select list, not in the CDS header. The snippet uses the standard lower model's source alias Booking; if yours uses another alias, retain your existing field projection and add only the label above it. Keep the upper entity's ConnectionId as a direct projection, without a local label or an expression, so the marker can propagate.

Activate the lower entity. Open its Active Annotations and confirm that ConnectionId has EndUserText.label with the value Booking connection (Lesson 6) and the lower entity as its origin.

13.2 Compare suppression on and off ​

Start with the header setting from Part 4 still present in ZI_BOOKING_SEM_###:

abap
@Metadata.ignorePropagatedAnnotations: true

Activate the upper entity, then open or reopen its Active Annotations. Check both ConnectionId and FlightPrice against the first two rows below.

Temporarily remove the suppression annotation from the upper header, activate the upper entity, and reopen its Active Annotations. Check the last two rows.

Upper header settingElement and annotationExpected active valueExpected origin
Suppression is trueConnectionId → EndUserText.labelThe marker Booking connection (Lesson 6) is absentNo propagated marker origin
Suppression is trueFlightPrice → Semantics.amount.currencyCodeCurrencyCodeZI_BOOKING_SEM_###
Suppression annotation removedConnectionId → EndUserText.labelBooking connection (Lesson 6)The chosen lower entity: ZI_BOOKING_BASE_### or ZI_BOOKING_ASSOC_###
Suppression annotation removedFlightPrice → Semantics.amount.currencyCodeCurrencyCodeZI_BOOKING_SEM_###

Record the values and origins you observed in both states. The lower label appears when propagation is allowed; the amount reference remains because you declared it locally in Part 5.

If the marker does not appear with suppression removed, check:

  • The upper as select from clause names the lower entity you edited.
  • The lower label sits directly above Booking.connection_id as ConnectionId, and the activated lower entity shows the marker in Active Annotations.
  • The upper field is a direct projection of ConnectionId, with no local @EndUserText.label that overrides the marker.
  • The upper suppression annotation has been removed, the upper entity has been activated, and you reopened Active Annotations for the upper entity.

Resolve these checks and repeat the comparison; an unchanged display is not the expected result for this controlled experiment.

13.3 Restore the submitted model ​

Restore the upper header setting:

abap
@Metadata.ignorePropagatedAnnotations: true

In the lower entity, restore the original element label you saved. If there was no element label before the experiment, remove only the temporary Booking connection (Lesson 6) annotation.

Activate the lower entity and then the upper entity. Reopen the upper Active Annotations: the temporary marker should be absent, while the local FlightPrice → CurrencyCode relationship should still have ZI_BOOKING_SEM_### as its origin.

The final submitted model again suppresses inherited annotations, preserves the lower entity's original labeling, and keeps its required semantics locally defined.


Part 14 — Alias-change challenge ​

Create a temporary higher layer or temporary copy.

Rename:

text
CurrencyCode

to:

text
TransactionCurrency

Keep:

text
FlightPrice

Question:

What must the amount annotation on FlightPrice reference now?

Implement the correct annotation.

Activate.


Part 15 — Prove the reference with Active Annotations ​

Open Active Annotations for the alias-change model.

Verify:

text
FlightPrice
  ↓
TransactionCurrency

not:

text
FlightPrice
  ↓
CurrencyCode

Explain why the annotation must use the local CDS element name.


Part 16 — Inspect a text provider ​

Open:

text
/DMO/I_TRAVEL_STATUS_VH

Find:

text
TravelStatus
_Text

Find the annotation that tells the model that _Text supplies descriptive text.

Record:

text
Annotation:
Association:

Part 17 — Inspect the text target ​

Open:

text
/DMO/I_TRAVEL_STATUS_VH_TEXT

Find:

text
Language
Text

Record the annotation on the language field:

text
________________________________________

Record the annotation on the text field:

text
________________________________________

Part 18 — Draw the text model ​

Complete:

text
TravelStatus
    ↓
____________________
    ↓
TravelStatus Text
   ├─ ____________________
   └─ ____________________

Use:

text
association
language
text

in your explanation.


Part 19 — Text element vs text association ​

Explain the difference between:

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

and:

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

Your explanation must mention:

text
text in same entity
associated text provider

Part 20 — SQL Console ​

Query:

text
ZI_BOOKING_SEM_###

Return:

text
TravelId
BookingId
CustomerId
CustomerName
CarrierId
CarrierName
FlightPrice
CurrencyCode

Order by:

text
TravelId
BookingId

Question:

Does ABAP SQL need special syntax to select FlightPrice because it carries currency semantics?


Part 21 — Reasoning questions ​

Answer in your own words.

1. What is the purpose of a CDS annotation? ​

2. What is the difference between an element annotation and an entity/header annotation? ​

3. What does @Semantics.amount.currencyCode describe? ​

4. Why does it reference an element instead of a literal currency? ​

5. What is the quantity/unit equivalent? ​

6. What does @ObjectModel.text.element describe? ​

7. Does a text annotation retrieve the text data by itself? ​

8. What does @Semantics.text identify? ​

9. What does @Semantics.language identify? ​

10. What does @ObjectModel.text.association describe? ​

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

12. Why can calculations interrupt annotation propagation? ​

13. Why can renaming CurrencyCode require re-annotating the amount? ​

14. What does Active Annotations tell you? ​

15. Why are UI annotations deliberately not the focus of this lesson? ​


Optional challenge 1 — Semantic Route ​

Create your own semantic layer on:

text
ZI_ROUTE_ASSOC_###

Add:

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

Use:

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

Optional challenge 2 — Annotation investigation ​

Open Active Annotations for:

text
/DMO/I_FLIGHT
/DMO/I_CONNECTION
/DMO/I_CARRIER

For each, record one active semantic annotation and its origin.


Submission checklist ​


Useful ADT shortcuts and actions ​

ActionShortcut / menu
Open ABAP Development ObjectCtrl + Shift + A
Code completionCtrl + Space
Syntax checkCtrl + F2
Activate current objectCtrl + F3
Activate inactive objectsCtrl + Shift + F3
CDS Data PreviewF8
Active AnnotationsOpen With → Active Annotations
Format sourceShift + F1