Dump: Code based annotation on redefined SEGW Project

Have you implemented code based annotation on redefined Odata project and getting dump?

Symptom

An attempt was made to insert an entry into table ‘\CLASS=/IWFND/CL_MED_MDL_PROVIDER\METHOD=CREATE_CLUSTERED_MODEL\DATA=LS_VOCA_MODEL-ANNOTATION_TARGETS’. Updating
unique table key ‘PRIMARY_KEY’ resulted in a duplicate entry however. The key in question could be either the primary key or a secondary key.”

Prerequisites

You redefining existing (SAP standard) SEGW project where code based annotations are used.
In new service you added the additional code based annotation by redefining method MPC_EXT->DEFINE. Inside DEFINE method you are calling super->define( ) for original service to add it annotation, later in the code you have inserted new annotation. You get dump in backend system when you try to get metadata of service from the gateway.

Reason

Each annotation is given unique id by method CALCULATE_ENTITY_ID in class /IWBEP/CL_MGW_VOCAN_MODEL. It seems after original SEGW project has finished adding annotation and before new SEGW project starts to add annotations the value of counter variable mv_entity_id_counter in class /IWBEP/CL_MGW_VOCAN_MODEL get reset.

Solution

Influence the value of variable mv_entity_id_counter using pre-exit on method CALCULATE_ENTITY_ID in class /IWBEP/CL_MGW_VOCAN_MODEL.

First define a class say zcl_bc_vocan_model with two static methods get_counter and set_counter and static attribute.

CLASS zcl_bc_vocan_model DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .

PUBLIC SECTION.

CLASS-METHODS set_counter
IMPORTING
!iv_entity_id TYPE int4 .
CLASS-METHODS get_counter
RETURNING
VALUE(rv_value) TYPE int4 .
PROTECTED SECTION.
PRIVATE SECTION.

CLASS-DATA mv_entity_id_counter TYPE int4 .
ENDCLASS.

CLASS zcl_bc_vocan_model IMPLEMENTATION.

METHOD get_counter.
rv_value = mv_entity_id_counter .
ENDMETHOD.

METHOD set_counter.
mv_entity_id_counter = iv_entity_id .
ENDMETHOD.
ENDCLASS.

Next, enhance class /IWBEP/CL_MGW_VOCAN_MODEL and put a pre-exit on method CALCULATE_ENTITY_ID with the following code. While defining enhancement make sure you choose the option so that your enhancement have access to private attributes of class.

Put following code in pre-exit method.

METHOD ipr_zenhancement_name~calculate_entity_id.
DATA : lv_persist_counter LIKE core_object->mv_entity_id_counter .

lv_persist_counter = zcl_bc_vocan_model=>get_counter( ) .

IF core_object->mv_entity_id_counter IS INITIAL AND
lv_persist_counter <> 0 .
core_object->mv_entity_id_counter = lv_persist_counter .
ENDIF.
ENDMETHOD.

In DEFINE method of new OData service, after you have call super->define() call method zcl_bc_vocan_model=>set_counter setting the counter value to reasonably high value.

METHOD define.

super->define( ) .

zcl_bc_vocan_model=>set_counter( 1000 ) .

"put your annotation code here
ENDMETHOD define.

Leave a Reply