This blog post shares my experience about a particular issue I encountered working with an OData service created using ABAP Restful Application Programming model and one possible resolution.
The case is associated with an amount field in an CDS entity was exposed as an entity in the service definition.
Amount and currency fields in CDS view
A POST operation on this entity, i.e., create operation of the entity record, contained an amount of max possible length the data element can support. For example, the amount field netTransferPrice was exposed in the projection of CDS view ZC_OrderItems from a table field which is based on a domain WERTV6 which is of type CURR length 11 decimal 2.
Domain for price field
This domain, when used in a classic GUI screen, e.g., VK13, can support an amount field of maximum length of 9 integer places before the decimal point. Here is an example:
Database table also allows max 9 integer places for the field as shown below.
Max length of amount in table
But the OData service POST operation throws an exception CX_SY_CONVERSION_OVERFLOW when same amount field is used in request payload.
Exception in OData service POST operation
This poses an anomaly (at least that was the impression on me) between the behavior in GUI app and OData service created based on ABAP RAP.
Investigation:
We opened an incident to SAP. And working with them closely on this case ended up into an interesting fact about how the data type in OData service gets converted.
When digging deep into the issue, debugging the methods revealed more information. The obvious answer to why the error is thrown was evident in the OData metadata.
The amount property was derived in the metadata as of type Edm.decimal with precision 12 and 3 decimal places.
This means that data Element is of type CURR length 11 decimal 2 which is converted to P(6) Decimal 3. In SADL utility class this happens as shown below:
Note: To be able to debug into above class and method, metadata cache needs to be cleared and then load metadata again from /IWFND/MAINT_SERVICES. Please see below steps for reference.
- Go to 'Service Implementation'
- 2. Click on 'Cleanup Cache' button, This will clear the metadata cache.
3. Come back to the main screen of /IWFND/MAINT_SERVICES. Click on 'Load metadata' button.
- This will trigger the SADL exposure classes again and one can debug the inner workings of them.
Solution:
The amount field exposure can be altered. There is a logic in the same class to overwrite the data type in some cases.
Above image shows the exact cases where an iverwrite of the decimal data type will be applicable. The names of the check methods for each of the cases is somewhat self-explanatory. Data type overwrite will happen if
- entity has text associations or
- entity has parameter or
- entity is an analytical query
- entity has field control properties
- entity has custom fields
I went ahead and added the standard CDS view I_CurrencyText as a Text association to the existing CDS entity.
Text association to I_CurrencyText
The association was also exposed in projection:
The currency field is annotated with annotation @ObjectModel.text.association to point to the Text view thus added above.
Annotation for Text association to Currency Text
Now the fix is done and time to check if it works.
Loading the metadata again and debugging the same point in SADL exposure class, if we inspect the entity properties inside the method cl_sadl_exposure_check
=>entity_has_text_association, we can notice the element CURRENCYNAME is added with a new entity_alias x8 which represents the text association for the field.
Properties and alias in SADL exposure
This invokes the internal overwrite of the amount property. The resultant metadata is shown below:
Amount and currency fields in Metadata
Please note the sap:text annontation now in the metadata for property 'Currency'.
Now the same payload works in POST operation!
Lessons learnt:
Adhering to the best practices matter. As it is seen here, the currency field can have different texts in different languages, so adding it as a text association fixed the issue. Also, a measure field should always be used with its appropriate unit in CDS views.
Cheers!