Application Development and Automation Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
Pradeep555
Discoverer
977

Virtual elements and  Performance :

What are Virtual Elements? 

A virtual element is typically used in CDS views to derive calculated fields dynamically without storing them in the database.
Suppose if we want to use any ABAP resources that would get more info for us Such as any informative fields or any function modules needed to be included in cds  
We go for virtual element 

Virtual Elements, those little pieces of code that are helpful to calculate certain things and add certain fields during runtime. . 
Anyway, there is no way around: 

For instance, taking the example: 

Suppose we need to calculate Delivery Lead Time of a particular order based on Order Date and Delivery Date 
Assume for a moment that this calculation couldn’t be done with CDS Views. 
In that case, you could create a Virtual Element in a CDS View. 
Because that Virtual Element would execute ABAP code to perform the logic mentioned above, Subtracting (ORDER DATE – DELIVERY DATE ) 
And you surely can solve the problem with ABAP. 
Then, that ABAP code would be executed each time the Virtual Element is accessed on the CDS View, solve the problem, and return the result to the CDS View.  

Code PushDown :
Code pushdown results in improved performance, as the amount of data that needs to be transferred between the database and application is reduced. 
Code push down can be achieved by using SQL Script or by using the HANA-optimized CDS language syntax 
Well, the concept of Code Pushdown is to handle logic on the database instead of the application server. 

Why? 

  • CDS Views get executed on the database. 
    CDS Views are actually nothing more than syntactic sugar for SQL. 
    If you execute a CDS View, you execute a SQL statement at the end. 
    Well, and SQL gets executed on the database. 
    Again, RAP has the execution of logic on the database layer as a fundamental concept. 
    CDS Views execute logic on the database layer. 
    Surprise, CDS Views as part of RAP are a perfect match. 
    So why do I bother you with those details above you ask? 
    Well, now with those things being said and keeping those in mind, let’s make the transition to what Virtual Elements actually are. 

  flow1.png

Before anything else, why avoid Virtual Elements? 
Because . . . if you use Virtual Elements, you undermine one of the fundamental principles of RAP (Restful ABAP Programming). 
CDS Views are a cornerstone of RAP. 
Thus, the entire purpose of CDS Views is to support RAP. 
And one of the core objectives of RAP is the Code Pushdown. 

 Annotations used for virtual elements :

 

@ObjectModel.virtualElementCalculatedBy: 'ABAP:ZCL_PD_SALES_VE'
@EndUserText.label: 'Delivery Lead Time'//
virtual DeliveryLeadTime : abap.int4Interfaces used :

 

INTERFACES : if_sadl_exit .

INTERFACES : if_sadl_exit_calc_element_read .

Methods :

Methods : get_calculation_info

Methods : calculate

  • Method GET_CALCULATION_INFO is used to provide the list of fields which is required for the calculation.
  • Method CALCULATE is actual method where we implement the custom logic.

    Virtual Elements  Vs CDS view

    Well, CDS Views can solve any problem that a computer can, with enough time and memory. 
    CDS Views can do any computation that doesn’t require infinite resources. 
    Therefore, take a closer look at your requirement at hand and ask yourself whether the logic necessary can’t be done in a reasonable way with CDS Views. 
    I say “reasonable way” because, while CDS Views might be Turing-complete, that doesn’t mean you should do any computation with CDS Views. 
    Especially due to performance reasons. 

    scenario :

    • Calculated Field: Delivery Lead Time 
    • Input Fields: Order Date , Delivery Date. 

      Formula: 

      • Delivery Lead Time = Order Date – Delivery Date 

        Steps :

        1.Create a db table with respective fields.

 

@EndUserText.label : 'table for virtual element' 

@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE 

@AbapCatalog.tableCategory : #TRANSPARENT 

@AbapCatalog.deliveryClass : #A 

@AbapCatalog.dataMaintenance : #RESTRICTED 

define table zpd_dt_ve_dlt { 

key client            : abap.clnt not null; 

key order_id          : sysuuid_x16 not null; 

order_date            : abap.dats; 

deliverydate          : abap.dats; 

local_created_by      : abp_creation_user; 

local_created_at      : abp_creation_tstmpl; 

local_last_changed_by : abp_locinst_lastchange_user; 

local_last_changed_at : abp_locinst_lastchange_tstmpl; 

last_changed_at       : abp_lastchange_tstmpl; 

} 

 

2.Create a root view entity for the table 

 

@AccessControl.authorizationCheck: #CHECK 

@Metadata.allowExtensions: true 

@EndUserText.label: '###GENERATED Core Data Service Entity' 

define root view entity ZR_PD_DT_VE_DLT 

as select from zpd_dt_ve_dlt 

{ 

key order_id         as OrderId, 

order_date           as OrderDate, 

deliverydate         as Deliverydate, 

@Semantics.user.createdBy: true 

local_created_by     as LocalCreatedBy, 

@Semantics.systemDateTime.createdAt: true 

local_created_at     as LocalCreatedAt, 

@Semantics.user.localInstanceLastChangedBy: true 

local_last_changed_by as LocalLastChangedBy, 

@Semantics.systemDateTime.localInstanceLastChangedAt: true 

local_last_changed_at as LocalLastChangedAt, 

@Semantics.systemDateTime.lastChangedAt: true 

last_changed_at       as LastChangedAt 

} 

 

3.Now create a projection view  on top of that and deifne the interface and class for virtual element as well.

 

@Metadata.allowExtensions: true 

@EndUserText.label: '###GENERATED Core Data Service Entity' 

@AccessControl.authorizationCheck: #CHECK 

define root view entity ZC_PD_DT_VE_DLT 

provider contract transactional_query 

as projection on ZR_PD_DT_VE_DLT 

{ 

key OrderId, 

    OrderDate, 

    Deliverydate, 

    LocalCreatedBy, 

    LocalCreatedAt, 

    LocalLastChangedBy, 

    LocalLastChangedAt, 

    LastChangedAt, 

@ObjectModel.virtualElementCalculatedBy: 'ABAP:ZCL_PD_SALES_VE1' 

@EndUserText.label: 'Delivery Lead Time' 

virtual DeliveryLeadTime : abap.int4 

} 

 

Interface we need to select before creating class. Virtual key and respective data element is mandatory

4.Now create behavior definition - projection behaviour defintion  projection implementation in class 

 

projection implementation in class ZBP_C_PD_DT_VE_DLT unique; 

strict ( 2 ); 

use draft; 

define behavior for ZC_PD_DT_VE_DLT alias ZcPdDtVeDlt 

use etag 

{ 

use create; 

use update; 

use delete; 

use action Edit; 

use action Activate; 

use action Discard; 

use action Resume; 

use action Prepare; 

} 

 

5.Behaviour definition for zr_pd_dt_ve_dlt

 

managed implementation in class ZBP_R_PD_DT_VE_DLT unique; 

strict ( 2 ); 

with draft; 

define behavior for ZR_PD_DT_VE_DLT alias ZrPdDtVeDlt 

persistent table zpd_dt_ve_dlt 

draft table zpd_dt_ve_dlt_d 

etag master LocalLastChangedAt 

lock master total etag LastChangedAt 

authorization master ( global ) 

{ 

field ( readonly ) 

OrderId, 

LocalCreatedBy, 

LocalCreatedAt, 

LocalLastChangedBy, 

LocalLastChangedAt, 

LastChangedAt; 

field ( numbering : managed ) 

OrderId; 

create; 

update; 

delete; 

draft action Activate optimized; 

draft action Discard; 

draft action Edit; 

draft action Resume; 

draft determine action Prepare; 

mapping for zpd_dt_ve_dlt 

{ 

OrderId            = order_id; 

OrderDate          = order_date; 

Deliverydate       = deliverydate; 

LocalCreatedBy     = local_created_by; 

LocalCreatedAt     = local_created_at; 

LocalLastChangedBy = local_last_changed_by; 

LocalLastChangedAt = local_last_changed_at; 

LastChangedAt      = last_changed_at; 

} 

} 

 

6.Create service definition for consumption view

 

@EndUserText: { 

label: 'Service Definition for ZC_PD_DT_VE_DLT' 

} 

@ObjectModel: { 

leadingEntity: { 

name: 'ZC_PD_DT_VE_DLT' 

} 

} 

define service ZUI_PD_DT_VE_DLT_O4 provider contracts odata_v4_ui { 

expose ZC_PD_DT_VE_DLT; 

} 

 

7. Create virtual element class for writing respective logic.

 

CLASS zcl_pd_sales_ve1 DEFINITION 

PUBLIC 

FINAL 

CREATE PUBLIC . 

PUBLIC SECTION. 

INTERFACES if_sadl_exit . 

INTERFACES if_sadl_exit_calc_element_read . 

PROTECTED SECTION. 

PRIVATE SECTION. 

ENDCLASS. 


CLASS zcl_pd_sales_ve1 IMPLEMENTATION. 

METHOD if_sadl_exit_calc_element_read~calculate. 

TYPES : BEGIN OF ty_date_cal, 

          OrderDate TYPE dats, 

          DeliveryDate TYPE dats, 

          DeliveryLeadTime TYPE int4, 

        END OF ty_date_cal. 

DATA : int_tab TYPE TABLE OF ty_date_cal. 

int_tab = CORRESPONDING #( it_original_data ). 

LOOP AT int_tab INTO DATA(wa) . 

DATA(order_date) = wa-orderdate. 

DATA(delivery_date) = wa-deliverydate. 

wa-deliveryleadtime = delivery_date - order_date. 

MODIFY int_tab FROM wa. 

ENDLOOP. 

ct_calculated_data = CORRESPONDING #( int_tab ). 

ENDMETHOD. 

METHOD if_sadl_exit_calc_element_read~get_calculation_info. 

ENDMETHOD. 

ENDCLASS. 

 

 8.Bind the service  .

Pradeep555_0-1738566767835.png

9.After this select the entity and preview the data.

Pradeep555_1-1738582040489.png

Here we can see that virtual element field ‘Delivery Lead Time’ holding the calculated value at runtime  After the successful calculation of ‘ Delivery Lead Time’ with respect to order date. 

  • Virtual Element Calculation:  
    This involves: Calling the associated ABAP class or method (CALCULATE in the example above). 
    Performing the computation for each record at runtime. 
    Virtual elements are calculated dynamically and not stored in the database. 
    This means the system performs these calculations in memory, adding a small overhead compared to fetching static fields.

 

Thank you----

Regards 

Pradeep Ishwar

1 Comment
AmveshKumar
Explorer
0 Kudos

Thankyou for this it help a lots to boost the knowledge

Labels in this area