OData Gateway
Architect / Cross-trackintermediate

OData Gateway Part 6: GET_ENTITY and Key Handling

Key takeaway

Implement single-entity reads in SEGW: read keys from it key tab or converted keys, apply ALPHA conversion, handle composite and date keys, return 404 for missing entities, check authorization, and avoid the typical key mismatches between $metadata, URL and database.

Explanation

📌 KEY POINTS
✅ GET_ENTITY answers /EntitySet(key) — one record. Keys arrive in it_key_tab as name/value pairs (strings) and via io_tech_request_context->get_converted_keys.

✅ SAP keys often have leading zeros (VBELN, KUNNR, MATNR); convert with CONVERSION_EXIT_ALPHA_INPUT before selecting, or the record is "not found".

✅ If the entity does not exist, raise /IWBEP/CX_MGW_BUSI_EXCEPTION with textid resource_not_found — the client receives HTTP 404, not an empty 200.

⚠️ Fiori object pages call GET_ENTITY after navigation from the list. A key that works in the list but not in GET_ENTITY is the most common "object page empty" bug.

━━━━━━━━━━━━━━━━━━━━
▶ WHERE WE ARE

Part 5 made the service reachable. Now the single read that every object page uses.

━━━━━━━━━━━━━━━━━━━━
▶ 1. KEY INPUT

  • URL: /SalesOrderSet('0000004711') — single key.
  • Composite: /SalesOrderItemSet(SalesOrder='0000004711',SalesOrderItem='000010').
  • it_key_tab: table of name/value (external property names, values as strings).
  • io_tech_request_context->get_converted_keys( IMPORTING es_key_values = ls_entity ): values already converted into the entity structure's types.

━━━━━━━━━━━━━━━━━━━━
▶ 2. CONVERSIONS

  • Leading zeros: CONVERSION_EXIT_ALPHA_INPUT for VBELN, KUNNR, LIFNR; material has its own exit (MATN1).
  • Dates in keys: Edm.DateTime format in the URL (datetime'2026-01-31T00:00:00'); converted keys give the ABAP date.
  • Special characters: keys are URL-encoded by the client.

━━━━━━━━━━━━━━━━━━━━
▶ 3. READ AND MAP

  • SELECT SINGLE with the full key.
  • Map to er_entity (type from MPC).
  • Same mapping logic as GET_ENTITYSET — put it into one private method to avoid differences.

━━━━━━━━━━━━━━━━━━━━
▶ 4. NOT FOUND AND ERRORS

  • Not found → RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception with textid resource_not_found and entity_type → HTTP 404.
  • Missing key → business error with a clear message (400).

━━━━━━━━━━━━━━━━━━━━
▶ 5. AUTHORIZATION

  • Check the record's authorization (e.g. V_VBAK_VKO with sales org, channel, division) — GET_ENTITY must not reveal records the list would hide.

━━━━━━━━━━━━━━━━━━━━
▶ 6. KEY TROUBLESHOOTING

  • Compare $metadata key properties, list response keys and GET_ENTITY URL.
  • Check that the list returns keys with the same format (leading zeros) that GET_ENTITY expects.

━━━━━━━━━━━━━━━━━━━━
▶ STEP BY STEP

  1. Redefine SALESORDERSET_GET_ENTITY.
  2. Read the key, apply ALPHA conversion, SELECT SINGLE.
  3. Raise resource_not_found when sy-subrc <> 0.
  4. Add AUTHORITY-CHECK on V_VBAK_VKO.
  5. Test with '4711' and '0000004711' and a non-existing number.

✅ CHECKPOINT: GET_ENTITY returns the right record for any key format, 404 when missing, and respects authorizations.

Code example

ABAP Code
* ===== STEP 1: DPC_EXT - SALESORDERSET_GET_ENTITY =====METHOD salesorderset_get_entity.   DATA: ls_key   TYPE /iwbep/s_mgw_name_value_pair,        lv_vbeln TYPE vbeln_va,        ls_vbak  TYPE vbak. * ===== STEP 2: read key from it_key_tab =====  READ TABLE it_key_tab INTO ls_key WITH KEY name = 'SalesOrder'.  IF sy-subrc <> 0.    RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception      EXPORTING        textid  = /iwbep/cx_mgw_busi_exception=>business_error        message = 'Key SalesOrder is missing'.  ENDIF. * ===== STEP 3: leading zeros =====  CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'    EXPORTING      input  = ls_key-value    IMPORTING      output = lv_vbeln. * ===== STEP 4: read and handle not found (HTTP 404) =====  SELECT SINGLE vbeln erdat kunnr netwr waerk vkorg vtweg spart    FROM vbak    INTO CORRESPONDING FIELDS OF ls_vbak    WHERE vbeln = lv_vbeln.  IF sy-subrc <> 0.    RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception      EXPORTING        textid      = /iwbep/cx_mgw_busi_exception=>resource_not_found        entity_type = iv_entity_name.  ENDIF. * ===== STEP 5: authorization for this record =====  AUTHORITY-CHECK OBJECT 'V_VBAK_VKO'    ID 'VKORG' FIELD ls_vbak-vkorg    ID 'VTWEG' FIELD ls_vbak-vtweg    ID 'SPART' FIELD ls_vbak-spart    ID 'ACTVT' FIELD '03'.  IF sy-subrc <> 0.    RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception      EXPORTING        textid  = /iwbep/cx_mgw_busi_exception=>business_error        message = 'No authorization for this sales order'.  ENDIF. * ===== STEP 6: map to entity =====  er_entity-salesorder = ls_vbak-vbeln.  er_entity-createdon  = ls_vbak-erdat.  er_entity-customer   = ls_vbak-kunnr.  er_entity-netamount  = ls_vbak-netwr.  er_entity-currency   = ls_vbak-waerk. ENDMETHOD. * 💡 Modern alternative: io_tech_request_context->get_converted_keys(*      IMPORTING es_key_values = ls_entity ) returns typed key values.

Real project scenario

A Fiori list showed sales orders correctly, but the object page stayed empty for every order. The list returned keys without leading zeros because a CONVERSION_EXIT_ALPHA_OUTPUT had been applied during mapping; GET_ENTITY then selected VBELN = '4711', which never exists in VBAK.
The fix removed the output conversion from the key property (display formatting was left to the UI) and added ALPHA input conversion in GET_ENTITY for robustness. The team moved mapping into one shared private method used by both GET_ENTITY and GET_ENTITYSET.

Common mistakes

  • Selecting without ALPHA conversion — "not found" for valid numbers.
  • Returning an empty entity with HTTP 200 instead of 404.
  • Different mapping logic in GET_ENTITY and GET_ENTITYSET.
  • Missing authorization check on single reads.
  • Reading key names in the wrong case ('SALESORDER' vs 'SalesOrder').

Best practices

  • Convert keys with the proper conversion exit.
  • Raise resource_not_found for missing records.
  • Share mapping between list and single reads.
  • Check authorization per record.
  • Test with padded, unpadded and invalid keys.

Interview angle

Questions: "How do you read keys in GET_ENTITY?", "Object page is empty but list works — why?", "How do you return 404?"
Strong answer: it_key_tab name/value pairs or get_converted_keys; ALPHA conversion for numeric-character keys; composite keys as multiple entries. Empty object page usually means key format mismatch (leading zeros, conversion exits) between list and GET_ENTITY. 404 via /iwbep/cx_mgw_busi_exception with textid resource_not_found; plus per-record authorization checks.

Practice this lesson

Quick check

1. GET_ENTITY for /CustomerSet('12345') finds nothing although customer 0000012345 exists. What is the fix?

2. GET_ENTITY finds no record for the requested key. What is the correct response behaviour?

3. How is an entity with a composite key addressed in an OData URL?

Interview questions

1. A material detail service returns not found for material 12345, but the material exists in SAP. What could be wrong?

Answer it in your own words first, then compare.

2. A Fiori list shows customers correctly, but the object page is empty for every customer. The list returns Customer = '12345'. What is likely wrong?

Answer it in your own words first, then compare.

Practice more with Interview AI →

Reference-verified: the steps are checked against official SAP documentation and tutorials, and object and field names in the sample code are checked for consistency. The code has not been compiled or run on an SAP system by ERPClimb. Syntax marked release-dependent varies by SAP release, so check it in your own system.

More lessons in this topic

Interview questions on this topic

Related SAP topics