on 2021 Apr 29 11:54 AM
Hi Experts,
We are currently migrating XS Classic oData services to Cloud Application Programming Model based services.In our previous application we had a XSOdata exposing a parametrized view which is using "key generate local " attribute to create a dynamic ID field.
When we Migrate to Cloud Application Programming Model do we have any equivalent attributes for entity or annotation aggregation to achieve the same result that we can using "key generate local "
Request clarification before answering.
The decisive sentence in the HANA docs is the very last one:
"As a consequence of the transient nature of generated local keys, it is not possible to define navigation properties on these entities or use them in filter or order by conditions."
With this modelling the generated key could be simulated:
entity E { i: Integer; };
service S {
view V as select from E { key null as k: Integer, i };
}
Translates into this API:
<EntityType Name="V">
<Key>
<PropertyRef Name="k"/>
</Key>
<Property Name="k" Type="Edm.Int32" Nullable="false"/>
<Property Name="i" Type="Edm.Int32"/>
</EntityType>
<Annotations Target="S.V/k">
<Annotation Term="Core.Computed" Bool="true"/>
</Annotations>
Core.Computed indicates that the key is generated and is to be ignored on a POST.
Of course the value for k must be calculated by a custom handler on each request.
It would even be possible to establish a navigation but as the key changes on every request, the modelling is questionable:
entity E { i: Integer; };
service S {
view V as select from E { key null as k: Integer, i };
entity X { key id: Integer; toV: association to V; };
}
Translates into OData:
<EntityType Name="X">
<Key>
<PropertyRef Name="id"/>
</Key>
<Property Name="id" Type="Edm.Int32" Nullable="false"/>
<NavigationProperty Name="toV" Type="S.V">
<ReferentialConstraint Property="toV_k" ReferencedProperty="k"/>
</NavigationProperty>
<Property Name="toV_k" Type="Edm.Int32"/>
</EntityType>
And to HANA SQL:
CREATE VIEW S_V AS SELECT
NULL AS k,
E_0.i
FROM E AS E_0;
CREATE TABLE S_X (
id INTEGER NOT NULL,
toV_k INTEGER,
PRIMARY KEY(id)
)
WITH ASSOCIATIONS (MANY TO ONE JOIN S_V AS toV ON (toV.k = toV_k));
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi,
hans-joachim.both we tried "key generation simulation" as per your previous comment. When we tried the same as below
define view md_supported_country_view(P_LANG : String(2)) as
select from MD_Supported_Countries {
key null as main: Integer,
ID as md_supported_country_ID,
iso_code as md_supported_country_ISO_Code,
is_inbound as md_supported_country_Is_Inbound,
is_outbound as md_supported_country_Is_Outbound,
texts.value as md_supported_country_text
}
where
texts.lang = : P_LANG
and ID <> 0
and current = 'X';<img alt="" style="font-size: 15px; color: rgb(51, 51, 51);">
service caseManager {
entity SCVParams(P_LANG : String(2)) as select from CBTViews.md_supported_country_view(P_LANG: :P_LANG) {*} }
We are receiving error when we hit the exposed View entity in the url as below
Kindly suggest if we are doing it in the right manner
Thanks
Sahasranaman
Did you check that view caseManager_SVParams in the DB has a column 'main'?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
david.kunz2 can you help here? I can't comment on runtime/query issues.
A modified version of your sample looks like this:
entity MD_Supported_Countries {
ID: Integer;
iso_code: Integer;
is_inbound: Integer;
is_outbound: Integer;
value: Integer;
};
entity md_supported_country_view(P_LANG : String(2)) as
select from MD_Supported_Countries {
key null as main: Integer,
ID as md_supported_country_ID,
iso_code as md_supported_country_ISO_Code,
is_inbound as md_supported_country_Is_Inbound,
is_outbound as md_supported_country_Is_Outbound,
value as md_supported_country_text
};
service caseManager {
entity SCVParams(P_LANG : String(2)) as select from
md_supported_country_view(P_LANG: :P_LANG) {*} ;
}
And translates into this API:
<EntityType Name="SCVParamsParameters">
<Key>
<PropertyRef Name="P_LANG"/>
</Key>
<Property Name="P_LANG" Type="Edm.String" MaxLength="2" Nullable="false"/>
<NavigationProperty Name="Set" Type="Collection(caseManager.SCVParamsType)" Partner="Parameters" ContainsTarget="true"/>
</EntityType>
<EntityType Name="SCVParamsType">
<Key>
<PropertyRef Name="main"/>
</Key>
<Property Name="main" Type="Edm.Int32" Nullable="false"/>
<Property Name="md_supported_country_ID" Type="Edm.Int32"/>
<Property Name="md_supported_country_ISO_Code" Type="Edm.Int32"/>
<Property Name="md_supported_country_Is_Inbound" Type="Edm.Int32"/>
<Property Name="md_supported_country_Is_Outbound" Type="Edm.Int32"/>
<Property Name="md_supported_country_text" Type="Edm.Int32"/>
<NavigationProperty Name="Parameters" Type="caseManager.SCVParamsParameters" Partner="Set"/>
</EntityType>
<Annotations Target="caseManager.SCVParamsType/main">
<Annotation Term="Core.Computed" Bool="true"/>
</Annotations>
As well as this HANA SQL
CREATE TABLE MD_Supported_Countries (
ID INTEGER,
iso_code INTEGER,
is_inbound INTEGER,
is_outbound INTEGER,
value INTEGER
);
CREATE VIEW caseManager_SCVParams(IN P_LANG NVARCHAR(2)) AS SELECT
md_supported_country_view_0.main,
md_supported_country_view_0.md_supported_country_ID,
md_supported_country_view_0.md_supported_country_ISO_Code,
md_supported_country_view_0.md_supported_country_Is_Inbound,
md_supported_country_view_0.md_supported_country_Is_Outbound,
md_supported_country_view_0.md_supported_country_text
FROM md_supported_country_view(P_LANG => :P_LANG) AS md_supported_country_view_0;
CREATE VIEW md_supported_country_view(IN P_LANG NVARCHAR(2)) AS SELECT
NULL AS main,
MD_Supported_Countries_0.ID AS md_supported_country_ID,
MD_Supported_Countries_0.iso_code AS md_supported_country_ISO_Code,
MD_Supported_Countries_0.is_inbound AS md_supported_country_Is_Inbound,
MD_Supported_Countries_0.is_outbound AS md_supported_country_Is_Outbound,
MD_Supported_Countries_0.value AS md_supported_country_text
FROM MD_Supported_Countries AS MD_Supported_Countries_0;
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi,
I had the same kind of problem with the V2 proxy dumping on me ( for me because of the lack of a key field - as I wanted to use a different field then the entity GUID field as key in the actual ODATA service and did exclude the original key ).
So instead of selecting all fields in the entity definition - {*} - can you try writing out the fields you want indicate which one should be the key
entity .... as select from CBTViews(...) {
key md_supported_country_ID,
<other fields you want to add>
}
So the trick here being that you define the key yourself.
Not sure it works for your particular case but it did with mine.
Steven
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi steven.desaeger ,
We also tried the solution you suggested yes it works,but in our case there are some view where the fields from the already available artifacts cannot be taken as "key".Hence we are looking for a Dynamic key which can be added just like how "keys generator local" in XSC's XSOdata works .But otherwise the solution you mentioned is the ideal way.
Thanks
Sahasranaman
This is a pretty good explanation of what a 'generated local key' is: https://answers.sap.com/answers/337785/view.html
david.kunz2 is correct there is no corresponding CAP feature.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
In response to David Comment
Hi david.kunz2 Sorry for adding in comments session as somehow Im not able to reply for your message.
But as per the thread you have mentioned https://answers.sap.com/questions/784739/sap-cloud-application-programming-model--generate-.html ?
We tried the below
and we got the ID__ key in the service with V2 Proxy adapter version 1.5.1.
The sole purpose we had to use this dynamic key generator was we were facing an error while exposing Parameterized view as mentioned above without a "key" in all the "@sap/cds-odata-v2-adapter-proxy" adapter whose version is higher than 1.4.30 hence we had to create a dynamic key at cds service level without disturbing the available artifacts.But still we encounter the below error as still it is not recognizing "ID__"as
[cds] - GET /case-manager/SCVParams(P_LANG='EN')/Set
#2.0#2021 04 29 12:53:00:793#+00:00#ERROR#/cov2ap/Response#####daa00837-1ddd-4383-bfe5-361bbcc7ac5e##########daa00837-1ddd-4383-bfe5-361bbcc7ac5e#PLAIN##Cannot convert undefined or null to object#
Apr 29, 2021 12:53:00 PM Logger.js [daa00837-1ddd-4383-bfe5-361bbcc7ac5e] ERROR: Cannot convert undefined or null to object
TypeError: Cannot convert undefined or null to object
at Function.keys (<anonymous>)
at entityKey (/home/user/projects/v2proxycap/node_modules/@sap/cds-odata-v2-adapter-proxy/lib/index.js:2547:32)
at entityUri (/home/user/projects/v2proxycap/node_modules/@sap/cds-odata-v2-adapter-proxy/lib/index.js:2543:25)
at convertLocation (/home/user/projects/v2proxycap/node_modules/@sap/cds-odata-v2-adapter-proxy/lib/index.js:1878:22)
at convertHeaders (/home/user/projects/v2proxycap/node_modules/@sap/cds-odata-v2-adapter-proxy/lib/index.js:1871:7)
at convertProxyResponse (/home/user/projects/v2proxycap/node_modules/@sap/cds-odata-v2-adapter-proxy/lib/index.js:1721:11)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
We have also observer that in the "/home/user/projects/v2proxycap/node_modules/@sap/cds-odata-v2-adapter-proxy/lib/index.js" of "@sap/cds-odata-v2-adapter-proxy" with version greater than 1.4.30 the below method is working based on entity key where it is throwing error as it is not able to recognize the key whereas in the 1.4.30 is is working based on "entity.elements"
Kindly suggest a better way to overcome the issue of dynamic keys so that it is recognised by the V2 adapter
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi sahasranaman1990,
Sorry, I was too eager to reply to your post, but I deleted it because the other question was a bit misleading.
As far as I know there is no corresponding feature in CAP, but I forwarded this question to my compiler colleagues, maybe they know more.
Best regards,
David
User | Count |
---|---|
53 | |
9 | |
8 | |
6 | |
6 | |
5 | |
5 | |
5 | |
5 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.