DPC Code Related Issues with SADL-Based OData Services. Troubleshooting
Have you run into problems when modifying runtime artifacts that were generated by the creation of an OData service in transaction SEGW?
Well, this blog post is here to help. Its purpose is to unravel common misconceptions about the untouchable generic code by the SADL framework and your self-implemented custom code. In other words, it provides solutions for problems that arise if you modify the generated runtime artifacts of an OData Service.
The runtime artifacts, generated by SADL help you to achieve better performance or even assure functionality for data retrieval or data modification. It is nice and easy that the framework provides these features for you. However, as soon as you want to modify or enhance the service with other application specific features, it might be that exactly these generated artifacts cause trouble, since you don’t even know clearly what they do and how they do it.
I have collected some common problems that arise when users manipulate a service that has been created with the SEGW. Find your particular “trouble” and shoot it with the solution provided.
- Performance violation in response time when using the query option $expand in mixed scenarios
- Short dump when using $batch in mixed scenarios;
- Error message “Default changeset implementation allows only one operation” in UI
- Navigation or $expand from an application-implemented (non-SADL) entity set to an entity set implemented by SADL fails
- Redefinitions of the methods GET_ENTITY and GET_ENTITY_SET are ignored when $expand is executed
- Message or exception gets lost and does not appear in UI
General Considerations on Generating an OData Service with the SEGW
It is recommended that only referenced data source (RDS) is used when creating an OData service with transaction SEGW. With RDS, the SADL framework automatically implements the methods that are necessary for retrieving modifying data with OData in the data provider class (DPC). These methods of the DPC must not be changed by the application developer. When using only RDS, they are automatically optimized with respect to functionality and performance. If you need to modify your service and you want to redefine methods, use the DPC_EXT class.
More info about OData Services created with RDS: Creating an OData Service Based on a References Data Source (RDS).
If the service is provided based on mapped data source (MDS), the DPC contains other methods than when generated based on RDS only. Some methods, for example GET_EXPANDED_ENTITY (which optimizes performance when using the query option $expand) that are automatically provided by SADL when using RDS are not generated in the DPC with MDS. Consequently, you might want to implement the functionality of these methods manually in the application specific DPC_EXT.
More info about OData Services created with MDS: Creating OData Services Based on a Mapped Data Source
The same holds true for mixed scenarios. We speak of mixed scenarios if you create a service using RDS and then add entities based on MDS to the service. The DPC contains the same methods as with MDS only.
Likewise, if you include non-SADL entities to your service, the automatically generated optimized methods of the DPC cannot be used for these foreign entities. The processing of these entities must be manually implemented by the application developer in the DPC_EXT since SADL does not know that these entities are part of the service.
Bear in mind that redefinitions in the DPC_EXT are the responsibility of the application developer. As soon as you redefine a method in the DPC_EXT, you are responsible for including any message handling or exception handling which is provided by SADL in the DPC.
Performance violation in response time when using the query option $expand in mixed scenarios
When executing an OData request that contains the query option $expand, the end-to-end response time excessively exceeds the norm.
In RDS-only scenarios the generated DPC uses the SADL expand, which implements performance-optimized execution for $expand requests. By manipulating the service with non-RDS-entities, the DPC overrides the methods GET_EXPANDED_ENTITY and GET_EXPANDED_ENTITYSET of generated DPC in the RDS-only scenario with the default implementation for $expand requests by Gateway. The performance drops significantly since multiple single roundtrips are executed by the Gateway runtime.
Note: Although the DPC of the MDS scenario also defines the expand methods GET_EXPANDED_ENTITY and GET_EXPANDED_ENTITYSET, they just call the methods of the super class that is generated by gateway.
To avoid performance issues due to looping across every involved entity, you need to redefine the expand methods GET_EXPANDED_ENTITY and GET_EXPANDED_ENTITYSET in the DPC_EXT. The logic of the improved SADL-expand must be implemented. A detailed description ofhow this is done can be found in the guide Fine-Tuning the Execution of SADL-Based Gateway Services in the chapter Improving OData $expand Performance.
Short dump when using $batch in mixed scenarios;
Error message “Default changeset implementation allows only one operation” in UI
When executing an OData request that contains $batch, the system dumps with the message ‘Commit work during changeset processing not allowed’ or the UI displays the error message “Default changeset implementation allows only one operation”.
In RDS-only scenarios, the generated DPC implements the methods that are used to execute $batch requests: CHANGESET_BEGIN and CHANGESET_PROCESS. When manipulating the service using non-RDS entities, the DPC does not implement these batch methods but calls the superclasses. The changeset cannot be processed as soon as the changeset contains more than one operation because the super methods only handle changesets with one operation. Therefore the $batch request cannot be executed and the system dumps.
You need to implement the methods responsible for batch processing in DPC_EXT. For the redefinition, call the SADL framework with IF_SADL_GW_DPC_UTIL~GET_DPC()~CHANGESET_BEGIN and IF_SADL_GW_DPC_UTIL~GET_DPC()~CHANGESET_PROCESS to add full batch logic to your service.
Navigation or $expand from an application-implemented (non-SADL) entity set to an entity set implemented by SADL fails
When executing an OData request with $expand or using a navigation property, you receive the error CX_SADL_CONTRACT_VIOLATION.
The behavior of the service differs depending on which entities are used.If an entity is not mapped using SADL (RDS or MDS), the navigation needs to be implemented by the application developer. Non-SADL entities are not known by SADL and thus cannot be processed. The framework does not provide navigation or expands to entities that are manually included to the service. Only navigation between SADL-implemented entities works automatically.
Associating manually implemented entities with MDS entities requires custom fine-tuning of the gateway service. To bridge manual implementations and MDS entities you cam make use of the query options API. You can find a detailed description on how to handle OData navigation for non-SADL entities here: Handling OData Navigation.
Pleas note that bridging manual implementations and RDS entities is not possible.
Redefinitions of the methods GET_ENTITY and GET_ENTITY_SET are ignored when $expand is executed
You have redefined the methods GET_ENTITY and GET_ENTITY_SET in DPC_EXT. When executing an OData request in which the query option $expand is used, the behavior of the redefined methods in the DPC_EXT is not observed.
The methods GET_EXPANDED_ENTITY and GET_EXPANDED_ENTITTYSET that are implemented in the DPC provide improved performance of the query option $expand. The optimized SADL expand does not call GET_ENTITY or GET_ENTITY_SET of the DPC_EXT. The getter methods are included in the expand methods with improved performance, this means your redefinition is ignored.
You need to redefine the methods GET_EXPANDED_ENTITY and GET_EXPANDED_ENTITYSET in the DPC_EXT and implement the same logic of your redefined getter methods GET_ENTITY and GET_ENTITY_SET. When requesting data with $expand, only the expand getter methods are called, which means any redefined getter logic must be redefined in these methods as well.
Message or exception gets lost and does not appear in UI
You have redefined a method in the DPC_EXT. A message which is included in the error handling in the generated DPC does not show up where it is expected.
The methods that are automatically generated in the DPC provide complete functionalities that handle messages and exceptions. That means that every issue that might arise is handled with exceptions and messages for every use case. If you redefine methods in the DPC_EXT you are responsible for providing adequate message handling and exception handling. The functionalities for messages and exceptions are not automatically reused in redefined methods.
Check the code in DPC_EXT. Pay particular attention to code lines that handle exceptions and messages. We have come across many issues in which SADL-specific exceptions are caught in production customer code. You as the application developer are responsible for not suppressing exceptions or messages that are created by SADL in DPC.