logo

Are you need IT Support Engineer? Free Consultant

Custom Root Entity Use case along with custom mess…

  • By sujay
  • 30/06/2026
  • 22 Views

A Custom Entity has no real table linked to it. RAP cannot read it automatically. Instead, it creates an empty structure and hands over the control to you. You then write your own ABAP code inside a Query Provider Class (QPC).

Custom Root Entity Example

@EndUserText.label: 'Custom Root Entity'

@ObjectModel: {
  query: {
    implementedBy: 'ABAP:ZCL_SALES_STATUS'
  }
}

@UI: {
  headerInfo: {
    typeName: 'SalesData',
    typeNamePlural: 'SalesData',
    title: { value: 'Salesorder' },
    description: { value: 'Itemno' }
  }
}

define root custom entity ZCR_CUSTSO_VIEW
{

  @UI.lineItem: [{ position: 10 , label: 'Sales Order' }]
  @Consumption.filter.mandatory: true
  @Search.defaultSearchElement: true
  @UI.identification:[{ position: 10 , label: 'Sales Order'}]
  key Salesorder : vbeln_va;

  @Consumption.filter.mandatory: true
  @Search.defaultSearchElement: true
  @UI.lineItem: [{ position: 20 , label: 'Sales Order Item' }]
  @UI.identification: [{ position: 20 , label: 'Sales Order Item' }]
  key Itemno : posnr_va;

  @Consumption.valueHelpDefinition: [{
    entity: {
      name: 'ZStatus_VH', // Your Value Help View
      element: 'Value'    // Source field for Status
    },
    additionalBinding: [{
      localElement: 'Statusdesc',   // Target field in your app
      element: 'Description',       // Source field from Value Help View
      usage: #RESULT                // Passes data on selection
    }]
  }]

  @UI.lineItem: [{ position: 30 , label: 'Sales Order Status' }]
  @UI.identification: [{ position: 30 , label: 'Sales Order Status' }]
  Status : abap.char( 1 );

  @UI.lineItem: [{ position: 40 , label: 'Time Stamp' }]
  @UI.identification: [{ position: 40 , label: 'Time Stamp' }]
  Timestamp : timestampl;

  @UI.identification: [{ position: 50 , label: 'Status Description' }]
  @UI.lineItem: [{ position: 50 , label: 'Status Description' }]
  Statusdesc : abap.char(20);

}

As you have created a Custom Root Entity, you are not forced to fetch data from a database source.

You can validate the input before fetching the data, or you can write your validation logic along with the data retrieval because you are implementing the query yourself.

You can loop over the data, modify it, apply your own business logic, or perform any operation you require before returning the response.

CLASS zcl_sales_status DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

PUBLIC SECTION.

  INTERFACES if_rap_query_provider .

PROTECTED SECTION.
PRIVATE SECTION.

ENDCLASS.

CLASS zcl_sales_status IMPLEMENTATION.

METHOD if_rap_query_provider~select.

  DATA(lv_top) = io_request->get_paging( )->get_page_size( ).

  IF lv_top < 0.
    lv_top = 1.
  ENDIF.

  DATA(lv_skip) = io_request->get_paging( )->get_offset( ).

  DATA(lt_sort) = io_request->get_sort_elements( ).

  DATA : lv_orderby TYPE string.

  LOOP AT lt_sort INTO DATA(ls_sort).

    IF ls_sort-descending = abap_true.
      lv_orderby = |'{ lv_orderby } { ls_sort-element_name } DESCENDING |.
    ELSE.
      lv_orderby = |'{ lv_orderby } { ls_sort-element_name } ASCENDING |.
    ENDIF.

  ENDLOOP.

  IF lv_orderby IS INITIAL.
    lv_orderby = 'Salesorder'.
  ENDIF.

  DATA(lv_conditions) = io_request->get_filter( )->get_as_sql_string( ).

  SELECT FROM zebst_status_log
    FIELDS salesorder,
           itemno,
           status,
           statusdesc,
           timestamp
    WHERE (lv_conditions)
    ORDER BY (lv_orderby)
    INTO TABLE @DATA(lt_status)
    UP TO @lv_top ROWS
    OFFSET @lv_skip.

  IF lt_status IS INITIAL.

    IF lv_conditions IS NOT INITIAL.

      RAISE EXCEPTION TYPE zcx_rap_exception_provider
        EXPORTING
          textid = VALUE scx_t100key(

*           HOW TO ADD CUSTOM MESSAGE CREATED IN SE91 (ZMSG_STATUS)

            msgid = 'ZMSG_STATUS'
            msgno = '000'
          )
          previous = NEW cx_sadl_contract_violation( ).

    ELSEIF lv_conditions IS INITIAL.

      RAISE EXCEPTION TYPE zcx_rap_exception_provider
        EXPORTING
          textid = VALUE scx_t100key(

*           HOW TO ADD CUSTOM MESSAGE CREATED IN SE91 (ZMSG_STATUS)

            msgid = 'ZMSG_STATUS'
            msgno = '001'
          )
          previous = NEW cx_sadl_contract_violation( ).

    ENDIF.

  ELSE.

    IF io_request->is_total_numb_of_rec_requested( ).
      io_response->set_total_number_of_records( lines( lt_status ) ).
      io_response->set_data( lt_status ).
    ENDIF.

  ENDIF.

ENDMETHOD.

ENDCLASS.

Using this approach, you can display a custom message when the user clicks the Go button.

In Managed and Unmanaged RAP scenarios, it is not straightforward to display this type of validation message during the read operation because the framework handles the data retrieval automatically. However, with a Custom Root Entity and Query Provider Class, you have complete control over the query execution and can perform validations before returning the data.

Custom Exception Class

To display custom messages, you need to create a custom exception class by inheriting from the standard RAP Query Provider exception class.

CLASS zcx_rap_exception_provider DEFINITION
  PUBLIC
  INHERITING FROM cx_rap_query_provider
  FINAL
  CREATE PUBLIC .

PUBLIC SECTION.

  METHODS constructor
    IMPORTING
      !textid   LIKE if_t100_message=>t100key OPTIONAL
      !previous LIKE previous OPTIONAL.

PROTECTED SECTION.
PRIVATE SECTION.

ENDCLASS.

CLASS zcx_rap_exception_provider IMPLEMENTATION.

METHOD constructor ##ADT_SUPPRESS_GENERATION.

  CALL METHOD super->constructor
    EXPORTING
      previous = previous.

  CLEAR me->textid.

  IF textid IS INITIAL.
    if_t100_message~t100key = if_t100_message=>default_textid.
  ELSE.
    if_t100_message~t100key = textid.
  ENDIF.

ENDMETHOD.

ENDCLASS.

After creating this custom exception class, you can use your custom SE91 message class (for example, ZMSG_STATUS) to display meaningful validation messages directly in the Fiori application when the user clicks the Go button.

This approach gives you complete control over the read operation. You can validate user input, fetch data from any source, modify the retrieved data, implement custom business logic, and raise custom exceptions whenever required.

Source link

Leave a Reply

Your email address will not be published. Required fields are marked *

Chat with us on WhatsApp!