Skip to content

Lesson 2 Companion ​

Use this companion to explore the architecture and implementation from Lesson 2 in more depth.

It contains:

  • deeper architecture explanations;
  • technical distinctions that are useful when reviewing the lesson;
  • complete reference implementations;
  • practice-assignment reference solutions;
  • troubleshooting guidance;
  • current SAP documentation references.

How to use this companion

Complete the main lesson and practice work first when possible. Use this file to compare designs, review a complete implementation, or investigate why a particular choice was made.

Related Lesson 2 files:

  1. Lesson 2 — Introduction to ABAP CDS
  2. Lesson 2 Practice — Airport CDS Model

1. Lesson 2 in the course architecture ​

Lesson 1 established:

text
Runner
  ↓
Reader
  ↓
ABAP SQL
  ↓
Database Table

Lesson 2 changes only the Reader's data-source dependency:

text
Runner
  ↓
Reader
  ↓
ABAP SQL
  ↓
CDS View Entity
  ↓
Database Table

That makes CDS a concrete architectural improvement rather than an isolated syntax topic.

From Lesson 1, you already know:

  • OOP;
  • Reader/Runner separation;
  • ABAP SQL;
  • SQL Console;
  • Data Preview;
  • internal tables;
  • host variables.

The genuinely new concepts are:

  • Data Definitions;
  • CDS DDL;
  • CDS View Entities;
  • CDS element aliases;
  • CDS keys;
  • CDS activation;
  • CDS Data Preview;
  • consuming the CDS entity instead of persistence.

2. Why CDS belongs after basic SELECT ​

Because you have already read database data, CDS now solves a concrete problem.

Lesson 1 creates that context:

abap
SELECT FROM /dmo/carrier

That leads to a useful question:

Should every consumer couple itself directly to the persistence representation?

CDS introduces a reusable model:

text
Persistence
    ↓
CDS
    ↓
Consumers

This sequencing keeps the abstraction motivated.


3. Current SAP direction: View Entities ​

Current SAP documentation describes CDS View Entities as the modern CDS view type used to define reusable data models over sources such as database tables.

This lesson therefore uses:

abap
define view entity

and avoids the obsolete DDIC-based form for new development:

abap
define view

A CDS View Entity does not require the old @AbapCatalog.sqlViewName pattern used by DDIC-based CDS views.


4. Data Definition vs entity ​

This distinction is important because ADT presents a Data Definition repository object, while developers commonly talk about the CDS entity defined inside it.

Use:

text
Data Definition
  = repository object / source container

CDS View Entity
  = modeled entity defined in the source

Activation makes the entity available to consumers.

SAP's ADT documentation describes creation of an inactive Data Definition followed by activation of the CDS entity.


5. Why the first CDS header is small ​

This lesson uses:

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

ADT templates can include additional annotations depending on the backend/template.

Keeping the first header compact means you do not need to memorize annotations whose purpose has not yet been introduced.

SAP's own ABAP Flight Reference Scenario carrier example uses a similarly compact base:

text
@AccessControl.authorizationCheck
@EndUserText.label
define view entity /DMO/I_Carrier ...

It additionally includes semantic text metadata for its scenario.

Semantic annotations are introduced later in this course.


6. @AccessControl.authorizationCheck ​

#NOT_REQUIRED is intentional because this tutorial entity has no CDS access-control role.

However, #NOT_REQUIRED does not mean:

text
"CDS should always use #NOT_REQUIRED"

CDS access control is an important application-security mechanism.

When DCL is added later, Data Preview and SQL Console results can reflect CDS access controls.


7. Why use a source alias? ​

The source declaration:

abap
as select from /dmo/carrier as Carrier

allows:

abap
Carrier.carrier_id

instead of an unqualified field name.

This creates a habit that scales naturally when later lessons introduce:

text
joins
associations
multiple data sources

Source aliases also make CDS code easier to read.


8. CDS element aliases as a model contract ​

Persistence:

text
carrier_id
currency_code

CDS:

text
CarrierId
CurrencyCode

The alias is not just cosmetic.

Consumers of the CDS entity see the CDS element names.

For example:

abap
SELECT FROM zi_carrier_###
  FIELDS CarrierId,
         CurrencyCode

The consumer does not select carrier_id from that entity.


9. Why CDS View Entities list elements explicitly ​

Current CDS View Entity syntax does not use * in the element list to expose all source fields.

That is a useful modeling property.

A CDS data model should state the elements that belong to the entity.

It also prevents accidental exposure of new persistence fields merely because the underlying table changes.


10. CDS key semantics ​

The line:

abap
key Carrier.carrier_id as CarrierId

marks CarrierId as a key element of the view entity.

Important distinction:

text
CDS key
  = entity/model key semantics

database-table key
  = persistence uniqueness/index semantics

The CDS keyword does not add a unique database constraint to the source table.

For /DMO/CARRIER, the model key aligns naturally with the persisted key.


11. Activation model ​

The Data Definition is created inactive.

Activation:

text
Ctrl + F3

creates/updates the active CDS entity in the backend.

A successful syntax check is required before activation succeeds.

The latest editor text is not automatically the active model merely because it has been typed.

If Data Preview shows an older version, check whether the latest edit was activated.


12. Data Preview vs SQL Console ​

Both are valuable, but they answer different developer questions.

Data Preview ​

Useful for:

text
What data does this CDS entity expose?
Which columns are visible?
How does filtering/sorting look?

Current ADT Data Preview supports CDS DDL sources and normally retrieves a limited result set, with 100 records as the default.

SQL Console ​

Useful for:

text
Can I write this ABAP SQL query against the CDS entity?
What happens with WHERE / ORDER BY?
What element names does the consumer see?

A good sequence is:

text
Activate CDS
 ↓
Data Preview
 ↓
SQL Console
 ↓
Reader

13. Why keep the Reader? ​

It might be tempting after introducing CDS to remove the Reader and query CDS directly from the Runner.

That would weaken the OOP organization introduced in Lesson 1.

The architecture therefore keeps:

text
Runner
 ↓
Reader
 ↓
CDS

because each layer has a different role:

text
Runner = execution/output
Reader = application data-access contract
CDS    = reusable data model
Table  = persistence

Later, RAP will change the application architecture significantly, but this separation makes the responsibilities clear now.


14. Why the Runner does not change ​

The key design lesson is that the internal implementation changes:

text
Reader → table

becomes:

text
Reader → CDS

while the Runner still calls:

abap
reader->get_all( )
reader->get_by_currency( ... )
reader->get_by_id( ... )

This demonstrates encapsulation with a concrete example.


15. Why the Reader uses ABAP SQL aliases ​

The existing Reader API returns:

text
carrier_id
name
currency_code

The CDS model exposes:

text
CarrierId
Name
CurrencyCode

The Reader maps them:

abap
FIELDS CarrierId    AS carrier_id,
       Name         AS name,
       CurrencyCode AS currency_code

That keeps the Reader's public contract stable.

Without those aliases, a change to the internal source could unnecessarily ripple into the Runner.


16. Reference CDS source ​

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

define view entity ZI_Carrier_###
  as select from /dmo/carrier as Carrier
{
  key Carrier.carrier_id    as CarrierId,
      Carrier.name          as Name,
      Carrier.currency_code as CurrencyCode
}

Expected concepts:

text
Data Definition
View Entity
source alias
key
element alias
annotations

17. Reference SQL Console query ​

abap
SELECT FROM zi_carrier_###
  FIELDS CarrierId,
         Name,
         CurrencyCode
  ORDER BY CarrierId

The important observation is that the query uses CDS element names.


18. Reference Reader implementation ​

The public Reader API can remain from Lesson 1:

abap
CLASS zcl_carrier_reader_### DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC.

  PUBLIC SECTION.

    TYPES:
      BEGIN OF ty_carrier,
        carrier_id    TYPE /dmo/carrier-carrier_id,
        name          TYPE /dmo/carrier-name,
        currency_code TYPE /dmo/carrier-currency_code,
      END OF ty_carrier,

      tt_carriers TYPE STANDARD TABLE OF ty_carrier
        WITH EMPTY KEY.

    METHODS get_all
      RETURNING VALUE(carriers) TYPE tt_carriers.

    METHODS get_by_currency
      IMPORTING
        currency TYPE /dmo/carrier-currency_code
      RETURNING
        VALUE(carriers) TYPE tt_carriers.

    METHODS get_by_id
      IMPORTING
        carrier_id TYPE /dmo/carrier-carrier_id
      EXPORTING
        carrier    TYPE ty_carrier
        found      TYPE abap_bool.

ENDCLASS.

The implementation changes to CDS:

abap
CLASS zcl_carrier_reader_### IMPLEMENTATION.

  METHOD get_all.

    SELECT FROM zi_carrier_###
      FIELDS CarrierId    AS carrier_id,
             Name         AS name,
             CurrencyCode AS currency_code
      ORDER BY CarrierId
      INTO TABLE @carriers.

  ENDMETHOD.


  METHOD get_by_currency.

    SELECT FROM zi_carrier_###
      FIELDS CarrierId    AS carrier_id,
             Name         AS name,
             CurrencyCode AS currency_code
      WHERE CurrencyCode = @currency
      ORDER BY CarrierId
      INTO TABLE @carriers.

  ENDMETHOD.


  METHOD get_by_id.

    CLEAR:
      carrier,
      found.

    SELECT SINGLE FROM zi_carrier_###
      FIELDS CarrierId    AS carrier_id,
             Name         AS name,
             CurrencyCode AS currency_code
      WHERE CarrierId = @carrier_id
      INTO @carrier.

    IF sy-subrc = 0.
      found = abap_true.
    ENDIF.

  ENDMETHOD.

ENDCLASS.

19. Runner reference ​

No architectural change is required.

For example:

abap
METHOD if_oo_adt_classrun~main.

  DATA(reader) = NEW zcl_carrier_reader_###( ).

  DATA(carriers) = reader->get_all( ).

  out->write( carriers ).

ENDMETHOD.

The Runner does not need to know whether the Reader reads:

text
table
CDS entity
external source

The Reader's public contract is what matters to the caller.


20. Practice assignment reference: Airport CDS ​

The practice assignment creates:

text
ZI_AIRPORT_###

Reference source:

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

define view entity ZI_Airport_###
  as select from /dmo/airport as Airport
{
  key Airport.airport_id as AirportId,
      Airport.name       as Name,
      Airport.city       as City,
      Airport.country    as Country
}

21. Airport SQL Console reference ​

abap
SELECT FROM zi_airport_###
  FIELDS AirportId,
         Name,
         City,
         Country
  ORDER BY AirportId

22. Airport Reader reference implementation ​

Assuming the Lesson 1 practice Reader has this contract:

text
airport_id
name
city
country

the CDS-based implementation can preserve it.

abap
CLASS zcl_airport_reader_### IMPLEMENTATION.

  METHOD get_all.

    SELECT FROM zi_airport_###
      FIELDS AirportId AS airport_id,
             Name      AS name,
             City      AS city,
             Country   AS country
      ORDER BY AirportId
      INTO TABLE @airports.

  ENDMETHOD.


  METHOD get_by_country.

    SELECT FROM zi_airport_###
      FIELDS AirportId AS airport_id,
             Name      AS name,
             City      AS city,
             Country   AS country
      WHERE Country = @country
      ORDER BY AirportId
      INTO TABLE @airports.

  ENDMETHOD.


  METHOD get_by_id.

    CLEAR:
      airport,
      found.

    SELECT SINGLE FROM zi_airport_###
      FIELDS AirportId AS airport_id,
             Name      AS name,
             City      AS city,
             Country   AS country
      WHERE AirportId = @airport_id
      INTO @airport.

    IF sy-subrc = 0.
      found = abap_true.
    ENDIF.

  ENDMETHOD.

ENDCLASS.

The Runner can remain unchanged if its public Reader contract is unchanged.


23. Practice conceptual answers ​

Why introduce CDS if the Reader already works? ​

Because the Reader currently depends directly on persistence. CDS creates a reusable data-model contract that can be shared and enriched independently of individual Reader implementations.

Does CDS replace the database table? ​

No. In this example /DMO/CARRIER or /DMO/AIRPORT remains the persistence source.

Does CDS replace ABAP SQL? ​

No. ABAP SQL can consume CDS entities.

Does CDS replace the Reader? ​

No. They have different responsibilities.

Why can the Runner remain unchanged? ​

Because the Reader keeps the same public method contract while its internal data source changes.

Why use CDS aliases such as AirportId? ​

The CDS model defines its own business-oriented element names independently of persistence naming.


24. Common troubleshooting ​

Data Definition wizard does not show exactly the same template wording ​

ADT/backend versions can differ.

Choose a template that creates a CDS View Entity and confirm that the generated source uses:

abap
define view entity

Data Preview shows an older structure ​

Activate the Data Definition after the latest edit:

text
Ctrl + F3

Then refresh/reopen Data Preview.


Reader says CarrierId is unknown ​

Confirm:

  1. the CDS entity is active;
  2. the Reader selects from ZI_CARRIER_###;
  3. the CDS source exposes CarrierId;
  4. the ### suffix is consistent.

SQL Console cannot find the CDS entity ​

Confirm the Data Definition is activated.

Search for the entity with:

text
Ctrl + Shift + A

Reader compiles against the table instead of CDS ​

Search the Reader for:

text
/dmo/carrier

After the refactor, executable SQL in the Reader should select from:

text
zi_carrier_###

The /DMO/ type references in the Reader's public type declarations may still exist to preserve the existing public contract.


25. Topics deliberately outside Lesson 2 ​

These topics belong later:

text
CDS joins
CDS associations
cardinality
CDS parameters
aggregations
complex expressions
DCL roles
RAP behavior
projection views
service definitions
service bindings
OData
Fiori Elements

Lesson 2 establishes the data-model layer before those capabilities are added.


26. Suggested study time ​

SectionApprox. time
Why CDS / architecture10 min
CDS terminology and syntax15 min
Data Definition creation15 min
Code completion / activation10 min
Data Preview10 min
SQL Console10 min
Reader refactor20 min
Run and compare architecture10 min
Review5 min

27. Current SAP references ​