Skip to content


A virtual data source can be implemented freely in the server.

virtual DraftSheet {  
   keys = SheetId;  
   attribute SheetId Text;  
   attribute SheetName Text;  
   attribute Status Text;  

Example code - Virtual data source

It is also possible to base the virtual on a regular entity. This also generates helper methods in PL/SQL, to convert between these entity types.

virtual DraftSheet extends CustomerOrder {  
   attribute ExpectedRevenue Number;  

Example code - Virtual based on regular entity

A virtual is a new type of entity which is defined in the projection file. It can be described as a temporary entity. It behaves as an entity, and it can basically do anything that a normal entity can do.

The main difference is that it does not require an LU, so there are no business logic and restrictions attached to it. It is mainly for storing data temporarily, until the user decides that the data entry is finished.

Another important difference is that keys are created and handled automatically. Each virtual gets an Objkey and a ParentObjkey. The Objkey is the key for the record itself, and the ParentObjkey is used when there is a defined relationship, such as a reference or an array.

Virtual vs Structure

The list below shows the advantages of using a virtual instead of a structure:

  • It is possible to define arrays just like in a normal entity. There is no need to use a separate syntax.
  • A virtual behaves like an entity. This means the client does not have to handle it differently than any other entities, so the code is cleaner and more maintainable as the List component can be reused without any special cases.
  • The data is stored in the database, which means there is no need to send the data manually via an action with as many parameters as there are attributes.
  • It is possible to enable recovering of unfinished work or continue the assistant from a different client.

Example 1

This example shows how virtual is used to add a contact and its addresses.

entityset Contacts for Contact;  
virtual Contact {  
   attribute PersonId Text;  
   attribute Name Text;  
   array Addresses(PersonId) to Address(PersonId);  
virtual Address {  
   attribute PersonId Text;  
   attribute Address Text;  

action Finish Text {  
   parameter Objkey Text;  

In the example a Contact and an Address with attributes are declared. The contact can have zero or more addresses, which are specified with the array in the Contact. This is (except for having to declare the attributes) exactly the same as using a real entity (based on a LU).

When the example deploys, Developer Studio created two tables, one for each virtual. The tables are named after the projection with a suffix of '_T1', '_T2', and so on. Normally there is no need to manually keep track of these names. If there is a need to use the names explicitly, then a request for a method can be added, to address them in other ways without the suffix name.

Example 2

virtual PartVirtual {  
   crud = Read, Update, Delete;  

   attribute Contract Text;  
   attribute PartNo Text;  
   attribute Description Text {  
      label = "Part Description";  
   attribute SupplyCode Text {  
      label = "Supply Option";  
   attribute ConditionCode Text;  
   attribute ConditionCodeDescription Text;  
   attribute QtyDue Number {  
      label = "Quantity";  
   attribute UnitMeas Text {  
      label = "UoM";  

   attribute Gtin Text {  
      label = "GTIN";  
      fetch = "Part_Gtin_API.Get_Default_Gtin_No(part_no)";  

Example 3

virtual WageAnalyzeResultVirtual {  
   crud = Read;  
   ludependencies = WageHourEmployeeResult, WageHourSelectionMid;  

   attribute SupervisorId Text;  
   attribute SupervisorName Text;  
   attribute CompanyId Text;  
   attribute EmpNo Text;  
   attribute OrgCode Text;  
   attribute UserId Text;  
   attribute AccountDate Date;  

   attribute Normal Number;  
   attribute Overtime Number;  
   attribute Absence Number;  
   attribute Increments Number;  
   attribute Balance Number;  
   attribute Break Number;  
   attribute Lunch Number;  
   attribute Specified Number;  
   attribute BalanceAccrual Number;  
   attribute BalanceWithdrawal Number;  
   attribute Information Number;  
   attribute ExtraTime Number;  
   attribute PresenceTime Number;  
   attribute ScheduleTime Number;  
   attribute AgreementTime Number;  

   reference CompanyRef(CompanyId) to Company(Company);  

   reference CompanyPersonRef(CompanyId, EmpNo) to CompanyPerson(CompanyId, EmpNo);  

   reference CompanyOrgRef(CompanyId, OrgCode) to CompanyOrg(CompanyId, OrgCode);